
I cannot consistently write safe C/C++ code - JoshTriplett
http://robert.ocallahan.org/2017/07/confession-of-cc-programmer.html
======
ccommsxx
The worst thing about these kinds of articles is the troves of junior
programmers that never touched systems programming with a stick before but
will read this on hackernews today and sit in the office tomorrow lecturing
seasoned coders how they´re dumb for not having seen the light and using an
unsafe language.

This is how stupid cargo cult gets made, guys. It's easy to repeat some
talking points that you found on the rust homepage or another internet forum,
but doing that does not make you an enlightened programmer!

Do c/c++ for 10 years, like the author, and then you're qualified to comment
about the topic. If you're new to this, try to put your time into actually
learning about these topics and not just blindly repeating other peoples
opinions. Please don't say things like "c/c++ is unsafe and should not be
used" without understanding it first. And try to consider for a moment that a
humongous part of the critical software in the world is written in it. It is
the industry standard for all things embedded and low level. Consider that
maybe the reason for that is not that everybody outside of hacker news is
stupid.

The thing is, I'm not even saying the author is wrong (I don't think he is).
I'm just saying that circulating these kinds of opinion posts here and then
applauding each other for being such brilliant rust fanboys is not helpful.

~~~
simias
Beginners will feel overconfident and some will even try to teach more
experienced coders how to do things "right" regardless of these types of
articles. We've all been there and we probably still are in some fashion. I
don't see how that diminishes the value of TFA though.

Any kind of guidelines can be "abused" by taking it to the extreme without
actually taking the time to consider if it actually makes sense.

Also while I do have significantly more than 10 years of experience in C I
think it's silly to say that you can't criticize the language if you can't
recite the K&R by heart. You don't need to know all the intricacies of C's
aliasing rules to peruse the long list of CVEs caused by faulty memory
handling.

The world of computing changed drastically over the past decades, for a given
application maybe C or C++ was a great choice in the 90's, doesn't mean
there's no better alternative now.

People telling everybody to ditch C like it never existed and rewrite
everything in Rust or Go are silly and are probably the junior coders you're
talking about who lack real world experience. Doesn't mean that the opposite
reaction of "if it ain't completely broke don't fix it" is any more clever.

~~~
ccommsxx
Well, I agree with you on practically everything you said.

Just for the record, I never intended to imply that somebody should not
criticize their tools until they fully mastered them and I certainly don't
claim to have done so. I just (tried to) say that I don't like it when others
recite opinions from some blog post without even a basic understanding of the
issues at hand as I find it leads to a very superficial discourse. I also
didn't mean to imply that new projects should be done in C/C++ for the sake of
historical reasons or something similar.

In fact, I actually recently started working on a new project, written in rust
(!) in an industrial setting. Part of the reason for my original comment is
that I found there was _a lot_ of cult in content related to rust, in their
marketing material and on rust-related posts on HN. While I really like some
parts of the language, this aspect of the rust community is really turning me
off at the moment and I hope it will get better over time.

~~~
alfiedotwtf
Let's say you're a fresh grad and looking at options for you future dev
career:

Option 1. Spend the next 5 years learning the ins and outs of C++, where it
can bite you, where it can go wrong, all the intricate edge cases, etc... and
you'll come out a better C++ programmer. Hopefully after 5 years of hard
concentration, you may be able to write safe code (I still haven't met a C++
programmer that hasn't been burned by segfaults _in production_ ).

Option 2. Spend a _single_ month learning Rust. Play with it for another month
or even two just to be sure. Hopefully after the 3rd month, they'll be 100%
certain that their code won't break because of errors that are above their pay
grade.

I've done programming for over 12 years. x86 assembly and C for the earlier
years. Then I realised that higher level languages gave me the power to code
confidently without causing the errors that I was constantly seeing without
explanation.

After many years of HLL I wanted to go back down to the metal... after
everything that I knew, "C or C++, not even once".

Rust gives me the confidence to "compile once, run safe everywhere".

~~~
daemin
That assumes there will be no errors in the Rust compiler or runtime
environment to deal with. If there are then those would definitely be above
their pay grade.

~~~
alfiedotwtf
I'd take a bug within LLVM over my own any day

------
simias
I think this whole "competent coders don't make mistakes" is a testament to
the immaturity of the software development world. Real men write in assembly,
maybe C if they're a bit tired.

It would be like a construction worker saying "only noobs need a hard hat" or
a surgeon refusing to wash their hands because they're careful never to touch
anything contaminated. Or maybe simply refusing to wear your seatbelt because
you're a good driver.

Guns don't kill people, people do but if your gun has the bad habit of firing
randomly when you don't want it to I guess it's fair to blame the gun a little
bit as well.

~~~
adambard
> or a surgeon refusing to wash their hands because they're careful never to
> touch anything contaminated.

Fun fact, although perhaps this is specifically what you had in mind: This was
pretty much the case until Ignaz Semmelweis [1] noticed that washing your
hands caused patients to die less frequently. His suggestion was not well-
received by the establishment:

> "Some doctors, for instance, were offended at the suggestion that they
> should wash their hands, feeling that their social status as gentlemen was
> inconsistent with the idea that their hands could be unclean."

I'd apologize for going off on a tangent if it wasn't such an accurate
analogy.

[1]:
[https://en.wikipedia.org/wiki/Ignaz_Semmelweis](https://en.wikipedia.org/wiki/Ignaz_Semmelweis)

~~~
stupidcar
I don't think it's inaccurate at all. Software development needs a scientific
revolution equivalent to that of medicine, wherein every pattern and practice
has to be backed up by evidence from a randomised, controlled trial.

I remember sitting in a "software quality" workshop organised by a coder at an
old employer. He was enumerating various patterns and best practices, and yet
I realised that nothing he was saying was backed up by any evidence beyond
appeals to emotion and anecdotes. If he had been trying to sell me on a new
religion or a health product, I would have rejected his arguments out of hand,
so why should the standard be lower for software development?

~~~
OJFord
> I'd apologize for going off on a tangent if it wasn't such an accurate
> analogy.

> I don't think it's inaccurate at all.

 _an_ accurate - not _in_ accurate! :)

------
millstone
> I cannot consistently write safe C/C++ code. I'm not ashamed of that; I
> don't know anyone else who can.

With respect, two mistaken beliefs:

1: Only a few programmers can write safe code.

2: One will naturally encounter such programmers in the course of a
prestigious career working for a high-profile web browser company.

But mediocre programmers consistently write safe C/C++ code, every day. They
do it in the context of aviation, automotive, etc. They do it as part of a
much larger safety process, that is designed to be robust against faults at
all levels, from design through development through manufacturing through end-
user servicing. Software development is but one facet, and compliance to
MISRA, ISO 26262, etc is only the start.

Get to know them, and see how safe C/C++ code is actually written!

~~~
skrebbel
That's a different kind of safe than the OP means. You mean "does not crash,
produces the right results", he means "can'te be hacked".

A non-networked engine control unit is super hard to hack by simple virtue of
being unreachable from the internet. I bet if you run a fuzzer against your
perfectly safe aviation code you'd find lots and lots of security issues. But
those issues aren't important.

~~~
noir_lord
> I bet if you run a fuzzer against your perfectly safe aviation code you'd
> find lots and lots of security issues. But those issues aren't important.

As long as no one does something silly a decade from now when it comes to the
networking on the plane/ship/factory.

~~~
adrianN
The "Industrial Internet of Things" is currently a very hot buzzword. I fear
the worst.

------
kbenson
> I cannot consistently write safe C/C++ code. I'm not ashamed of that; I
> don't know anyone else who can. I've heard maybe Daniel J. Bernstein can

For anyone that thinks this, you might be interested to find that DJB himself
apparently thinks C, or at least the current state of C as implemented by the
common compilers, is untenable for important, long lived software.[1] At
least, that's how I interpreted his position. He was responded to as you would
expect, unfortunately.

Credit where it's due. [2]

1: [https://groups.google.com/forum/#!msg/boring-
crypto/48qa1kWi...](https://groups.google.com/forum/#!msg/boring-
crypto/48qa1kWignU/o8GGp2K1DAAJ)

2:
[https://news.ycombinator.com/item?id=14170585](https://news.ycombinator.com/item?id=14170585)

------
wfunction
> I cannot consistently write safe C/C++ code.

I'm not sure how to interpret what this means. What do "consistent" and "safe"
mean? Is safety about not corrupting program data? Even when dealing with
Python arrays, I can end up corrupting my arrays one way or another (off by
one, race conditions, etc.). Is "consistent" about going days without a bug?
Because I can't do that in _any_ language. If not, what do these mean? It'd be
really nice to know what other languages he can write safe code in, so we can
have something to compare to.

~~~
pjmlp
Of course every programming language is not perfect, including its library and
related implementations.

In all of them is possible to introduce logical bugs.

The problem with C and its derived languages is that not only one has the
logical bugs common to all programming languages, there are the memory
corruption and UB introduced bugs to worry about as well.

While one can think as being super competent, make use of all tools to reduce
such error cases, there are always situations where such errors get introduced
due to fatigue, project pressure, continuous interrupts.

Additionally since most of us don't work alone, the actual code quality is an
average of everyone that has ever worked on the code, and not everyone shares
the same goals regarding quality of their work.

I share the feeling with the author, always tried to follow C and C++ best
practices, when coding in C I adopted or evangelized tooling, safety standards
or known books that lead to safer code.

Yet, like everyone else I had my share of memory corruption issues back on my
C and C++ days.

One anecdote was trying to find out a memory leak that was bringing down a
server in production, with the customer calling technical support every single
day.

It took one week to track it down, and it wasn't something I would advise
anyone to experiment.

~~~
danieltillett
The good thing about C is there is an amazing tool support that can make it as
safe as any other language. The bad thing about C is that most developers
don’t know about (or don’t use) all the tools.

~~~
clarry
They don't even use their compiler.. case in point:
[https://news.ycombinator.com/item?id=14787072](https://news.ycombinator.com/item?id=14787072)

Of course they always just blame the language. Like the language needs to be
responsible for the implementation and its proper use.

~~~
kbenson
Any tool that requires special knowledge to use safely rather than
_defaulting_ to safe operation and requiring special knowledge to use unsafely
is poorly designed. If the design specification for that _class_ or tools
encourages or requires that, it's a poor specification indeed.

------
Loony2
I've worked in "IT security" as a C programmer for about 10 years. I both
agree and disagree with this article.

A competent C/C++ programmer will have a lot less of problems like buffer
overflows and crap like that, I don't think a buffer overflow has been found
in any code I've written during my 10 years as a C programmer.

I have still written code that has security issues though, most of them stem
from poorly designed code and are not necessarily a language problem.

I'm not claiming to be a super human here, I've had my fair share of gotchas,
like off by one errors and issues with pointer arithmetic when refactoring
code and so on and we might actually reduce the time needed to verify that C
code is safe if we change to another "safer" language, but I'm 100 % sure that
you still have the issue with poorly designed code even with a "safe"
language. And from my experience it's a lot harder to find those problems,
since you need to understand how the code base works and how it fits together
to find those issues.

~~~
kbenson
This is a rebuttal against "use a safe language and _all_ your security
problems go away entirely" but that is not generally the argument being
advanced. The argument that is generally advanced is "use a safe language and
_some_ of your security problems go away entirely".

Put another way, people are arguing for airbags to become much more common,
and your rebuttal is "I've gotten into some accidents, and I've gotten hurt in
ways an airbag would not have helped". That's entirely possible, but
irrelevant to the argument at hand (unless you also state that you _never_ get
into accidents where and airbag would help)..

Edit: Stating your position as a rebuttal may have been overstating it a bit.
It's entirely possible you're just attempting to add information to the
argument, in which case please read my comment as attempting to do the same.

~~~
Loony2
I agree, but I still believe that one issue here is the lack of understanding
of what the process around software development should be.

We would get rid of some issues if we used a safer language, but the real
issue is that we don't find the issues, the attacker does instead. So people
are finding the issues, but why are not the people writing the software
finding them?

I believe that you should have a development team that make sure there are no
issues to be found, no matter the language you are writing your application
in. That means you run the same tests, no matter the language, so in the end
it doesn't matter what language you write it in. And you chose a language that
fits the problem, you don't make the language fit the problem.

So I think your analogy of an airbag is wrong in some sense. The issue isn't
weather we have an airbag or not, the issue is that we don't test if we have
an airbag and then go "Whoops, the airbag didn't deploy in the crash and
somebody died".

We as programmers like to think of ourselves as engineers, but we don't treat
the profession as engineers, we very often deploy code we know are not tested,
we might even know it is buggy, you open yourself up to a lot of damage if you
do that as a bridge builder (even though it has happened).

I'm tired and this turned into a rant, but I hope that my point comes across.

EDIT: I don't mean that we should write bug free code, I mean that we should
strive for code without security issues. It can be done, I work at a place
where we have written code for 15 years, not only C code, or more without any
remote exploitable holes.

~~~
kbenson
> We would get rid of some issues if we used a safer language, but the real
> issue is that we don't find the issues, the attacker does instead. So people
> are finding the issues, but why are not the people writing the software
> finding them?

Attackers aren't finding all the issues. They are finding issues in the small
subset of software they actually bother to examine. That programmers aren't
finding the issues I think illustrates both the effort it takes to _always_ be
correct as well as the different skills that are leveraged differently. It
doesn't take a good C systems or application programmer to find a lot of the
common C unsafety errors in question. It takes someone that knows the C memory
model and has the knowledge of how to leverage that commonly. In some cases it
takes someone applying new fuzzing techniques to expose certain edge cases
more consistently that prior fuzzers did.

> That means you run the same tests, no matter the language, so in the end it
> doesn't matter what language you write it in.

The important point you are assuming is that the language (or _current
implementation_ of it) won't change out from under you in a way that makes
that assumption invalid. See my other comment in this discussion regarding
DJB, and the HN comment I link to for a good discussion about why that's so.

> And you chose a language that fits the problem, you don't make the language
> fit the problem.

In what case when you have two languages roughly similar in capability but one
allows errors the other doesn't is the one that allows the errors the better
fit?

> So I think your analogy of an airbag is wrong in some sense. The issue isn't
> weather we have an airbag or not, the issue is that we don't test if we have
> an airbag and then go "Whoops, the airbag didn't deploy in the crash and
> somebody died".

Then you're misunderstanding my analogy. The car isn't the program written,
the car is the compiler. The route driven is the program. You may make an
error on the drive, but let's let the car save us in those cases where it's
obvious it can and should. Sure, making sure your coworkers check you've
secured the pillows to the steering wheel before every trip works, but it
should be obvious why that's sub-optimal in multiple dimensions.

> I work at a place where we have written code for 15 years, not only C code,
> or more without any remote exploitable holes.

I congratulate you on your diligence (sincerely, it is an accomplishment to
get to the level where you feel you can say this), but that's a strong
assertion in at least one possible interpretation. Perhaps you meant no
remotely exploitable holes _found_? The interesting question that immediately
arises from that clarification is whether anyone has seriously looked?
Companies that care about this hire pen testers. I hope yours does as well.

------
barrkel
The more you know an a C++ programmer, the more you're aware of all the things
that can bite you and all the things you need to do to make sure you don't get
bitten. Writing code within that cognitive envelope is a tax that's often
underestimated. After spending some time out of that world, I find it
amazingly tedious to get back into it.

If you're not aware of many of the pitfalls, you might not even be aware of
the envelope you should be aware of.

------
faragon
Yet another subtle pro-Rust rant against C.

Programming is hard, and writing safe code requires knowledge, not just in C,
but in every single language. Even in formal-validable languages you can make
mistakes: may be you'll not make errors by using sprintf, but can make others
because of using a more complex language.

~~~
fulafel
Good risk management is about cost vs payoff analysis. To address the risk of
car accident, first you stop juggling chainsaws while driving, then you start
to wear seatbelts, and then you start thinking about how the remaining
inevitable driving mistakes can be mitigated through technology or practices.

~~~
millstone
I guess using C is analogous is juggling chainsaws in your analogy. But is
that actually less safe?

Consider a component _actually responsible_ for preventing car accidents, such
as the anti-lock brake system. It will consist of input sensors, output
signals, and an embedded computer running some code. All of these components
have gone through an extensive qualification process. On the software side,
the coding standard requires that all loops must be manifestly finite, no
`continue`, no recursion, etc. This coding standard is enforced by the
compiler, and the compiler itself must be certified, an extensive and
difficult process on its own. Redundancy and review is applied at multiple
levels, with tons of supporting tooling around requirements tracking and the
like.

Do that, and prove it over many years, and you can juggle chainsaws safely -
or ride an explosion under your feet across the country.

The key idea here is that things that have been proven safe, are safe. Using
something unproven like Rust, it's nuts. Think about how big LLVM alone is!
Rust doesn't have any of that, not the tooling, qualification, standards, or
track record. It could be done, but you would need to pour tons of resources
into it to bring Rust up to the level that C has in this space.

~~~
fulafel
This sounds like a very specialized C subset with nonstandad compilers,
tooling and highly restricted functionality. Why use C as the starting point
for such a language, instead of a hereditarily safer language like Pascal,
Ada, etc?

------
nec4b
I wonder how can anyone even use computers these days, since C and C++ are so
unsafe. My OS is written in C and C++, also my browser and my word processor,
my shell and most of the applications that I daily use. The firmware in my
phone, my set-up box and my car is also written in those two languages. Also
all the major web servers are written in those to languages. Maybe Rust
programmers are an exception, but I personally spend 99,99% of troubleshooting
time (in any language) on fixing logical bugs that I make. It's hard to get
excited about a language like Rust, when it seems that it's community is only
interested in spreading FUD.

~~~
clarry
"So unsafe."

The thing is, we (C programmers) are a careful bunch and we like to treat
everything as a potential security issue. Even if the likelihood of
exploitation on a real world system is literally nil. People see these fixes
and possibly associated security advisories, and they think it's all
exploitable. Then one actually exploitable bug from some 15-year-old code gets
publicized and the publicity spreads everywhere. Look, another exploitable
bug! C is sooo friggin bad and every line is an RCE waiting to happen!

I think the safety issue is blown way out of proportion because of that.

It doesn't help that when people discuss UB, they assume the most adversarial
compiler possible that literally does all it can to turn the UB into a big
problem. And that literally everyone has to be using that compiler and that
they may not use the compiler flags that turn off the bad behavior.

------
jhasse
How about you start writing C++ and not C/C++ code?

The two languages are so different, it isn't fair to mention them as if they
were the same.

~~~
Manishearth
The author worked on Firefox, a largely C++ codebase, so he _was_ writing C++.

I assume he feels that the problems he talks of are common to both languages,
if different in magnitude.

------
alok99
I'd be interested in trying an online coding exercise like the one he
mentioned. I've definitely fallen into the trap of thinking that my code was
robust because it worked for my specific use case (and no one tried to break
it). Now I feel much more skeptical that my code works at all.

------
jokoon
Safety, speed, language convenience.

Pick 2.

Safety is an issue everywhere you are programming something, good programmers
just know how to mitigate it.

And to be really honest, you don't always need to use C++. Just use it where
performance is needed, write good code, review it, etc, and when you need to
go at a higher level, use python or any other scripting languages. C++ should
be used to write libraries.

There are not so many softwares in the world that need to be entirely written
in C++, and if they do, more time is spent writing and fixing such software.

"There are languages people complain about, and languages nobody use".

I don't dislike rust, but when I read its syntax, it doesn't seem simple
enough to learn, read and write, the learning curve seems pretty steep, so it
won't really do well with students.

------
amelius
Isn't this the same as saying you can't consistently write bug-free code?

And isn't this sort of the holy grail of CS?

~~~
kbenson
You are conflating "safe" with "bug-free", when safety has a specific meaning
in this context, which is memory model safety. Safe code eliminates a _class_
of errors, and thus reduces the _possible_ bugs your program may exhibit.

At this point we can eliminate certain classes of bugs, and sometimes with no
runtime cost. The usual example used is Rust, where extra information supplied
in the source is used to ensure certain bugs are not possible at compile time.
It requires some extra work, but I think likely quite a bit less than the more
extreme coding standards used to produce safe C code, but those may cover a
different or larger subset of bugs.

------
Sir_Cmpwn
I really wish we would disconnect C and C++. They're different langauges used
entirely differently by different people, and C++ gives C a bad rep.

~~~
nikbackm
C is more than capable of getting a bad rep on its own.

------
superbatfish
I don't know what the Dunning-Kruger effect is, but I can tell you for a fact
I'm too smart for it to affect me.

------
irundebian
Nice post. There are still to many C/C++ wannabes who think C is an awesome
language and their are awesome hardcore programmers. If they are challenged to
code something, it's highly probable that flaws will come up.

~~~
stinos
_There are still to many C /C++ wannabes_

There are still too many people using the term C/C++ :] It never really was a
thing, even in the beginning (I mean, just take e.g. destruction at scope
exit: that alone makes it a very different language) and now even less with
the new standards.

Anyway: a language can be considered awesome by people, despite it's flaws.
Always has been, never will change, as there will probably never be languages
without any flaws. (e.g. I think Python is awesome, others don't ever cease
summing up it's flaws, I couldn't care less as it gets stuff done in
particular situations). Just like it's inevitable every single programmer,
including you, writes flawed code from time to time, challenged or not.

~~~
irundebian
> as there will probably never be languages without any flaws

Yes, but we can try to develop better language. Rust is such a try. And that's
good.

> Sure, but I don't belong to that fraction of programmers who think they
> write flawless code or develop a cult with old, error prone languages such
> as C.

The important thing is that we are not discussing about programmers making
mistakes, but about a language which is old and which is making mistakes easy.
C proofed in sufficient cases that it belongs to the museum.

~~~
stinos
_it belongs to the museum_

I agree that in C it's _way_ easier to make mistakes than in e.g. Rust, but I
don't agree that (or whatever other reason) is proof that it belongs in a
museum. Take microPython for instance: it's a relatively young project written
in C, it allows running a pretty complete Python 3 implementation on a variety
of microprocessors as well as on PC/mac/... Suppose we put C in a museum, what
do we use instead to achieve the same functionality?

------
sclangdon
It makes me smile when someone starts off a complaint with something similar
to "I've been programing in C++ for x decades. I have y qualifications that
should impress you. I worked at z company which should impress you further.
Yet, despite this, I cannot write safe C++ code".

The author's post, in particular, is excellent as it follows this token
introduction with "I don't know anyone else who can write safe C++ code,
either". This is further strengthened by "people I know to be skilled
programmers (based on what, I don't know), have never professed that they can
write safe C++ code, and therefore people who do, are obviously suffering from
some psychological effect".

I mean, really? You can't do it, and your friends can't do it, so no one can
do it? Even though there is a world of software out there that does exactly
what you say can't be done? And further, anyone who says they can do it must
be less-skilled and suffering for a form of illusory superiority complex? Get
over yourself.

How ironic that he knows about the Dunning-Kruger effect, but fails to apply
it to himself.

~~~
shusson
> Get over yourself

The guy is simply describing his personal experience. Why don't you describe
your own personal experience instead of attacking him?

