top | item 27459169

GNU Coding Standards: Writing Robust Programs

120 points| mpsq | 4 years ago |gnu.org

109 comments

order

kstenerud|4 years ago

> In error checks that detect “impossible” conditions, just abort. There is usually no point in printing any message. These checks indicate the existence of bugs. Whoever wants to fix the bugs will have to read the source code and run a debugger. So explain the problem with comments in the source.

But then the person RUNNING the program will only see this:

    Abort trap: 6
And that's all the info you'll get from their bug report.

So please ignore this directive and print a descriptive message always, complete with file and line, and the values that led to the impossible situation. Then you can get helpful bug reports like:

    BUG: flush.c:51: buff_offset (65535) must not be greater than 20!
    Abort trap: 6

jandrese|4 years ago

It's hard to imagine that directive lasting beyond the first bug report of "it broke, fix now!".

pjmlp|4 years ago

> When you want to use a language that gets compiled and runs at high speed, the best language to use is C. C++ is ok too, but please don’t make heavy use of templates. So is Java, if you compile it.

Back in the early days, this sentence was more like "When you want to use a language that gets compiled and runs at high speed, the best language to use is C.".

So we switched from a path where all major desktop environments (OS/2, Mac, Windows, UNIX) were adopting C++ to a surge in C programming, as FOSS adoption started to gain steam.

So here we are now, about 30 years later, trying to fix the security inconveniences caused by this manifesto.

st_goliath|4 years ago

> So we switched from a path where all major desktop environments ... were adopting C++ to a surge in C programming, as FOSS adoption started to gain steam.

So you say FLOSS is responsible that the late 90s/early 2000s C++ hype slowly died off?

> trying to fix the security inconveniences caused by this manifesto.

And you believe those projects chose C, solely because some random GNU document suggested they do?

If that document didn't exist they would have chosen what? C++98? Java? Ada?

cng100|4 years ago

The average C++ code base has as many segfaults than the average C code base.

Windows has more exploits than Linux. But you know all that, so I wonder why you keep making these statements, which are then upvoted by the "memory-safe" crowd.

ajross|4 years ago

> So here we are now, about 30 years later, trying to fix the security inconveniences caused by this manifesto.

That sounds backwards to me. It wasn't a "manifesto" that caused that "surge", it was the actual software being written.

Free software beat the world. Free (system) software is overwhelmingly written in C. At least part of an argument like this needs to nod to the fact that free software written in C beat the world because... C was a better choice? Certainly it was in the 90's.

quasit1|4 years ago

I've spent 10 years writing security critical C code. There's no problem writing secure code in C. You just have to stop being clever and prioritize security above "speed". Your code will probably be fast enough anyway.

If it's too slow, then you probably have an issue with which algorithm/data structure you chose and would have had the same issue in another language.

The biggest issue I have with C today is that you can't trust that your compiler actually generates code that is 1:1 with what you wrote. I'm not talking about UB here, your compiler can actually remove code/checks even though you don't invoke UB.

Then we have UB, I think UB should be removed from the spec completely. There probably was a point in time when leaving stuff as UB was the best option, but today speed is seldom the problem, correctness is.

I no longer work as a C programmer, but I still love the language and I really enjoy writing C code, but I really would like to get rid of UB and have a compiler I can trust to generate code even when I turn on optimizations, and having optimizations off is not an option either, since it can generate broken code as well, so...

varjag|4 years ago

C++ up to and including '98 spec was terrible from security perspective, not a iota better than plain C.

roenxi|4 years ago

I don't think there is a justification for the idea that 90s "C++" was going to be substantially different from C. You can call the C files C++ and be pretty much correct. Speculatively ... the OSS community would have converged on the C part of C++. That is the well understood part.

toyg|4 years ago

Yep, you see it also in the split away from Qt (C++) to GTK (C).

bigbillheck|4 years ago

I see that they still say:

>>> Please don’t use “win” as an abbreviation for Microsoft Windows in GNU software or documentation. In hacker terminology, calling something a “win” is a form of praise. You’re free to praise Microsoft Windows on your own if you want, but please don’t do so in GNU packages. Please write “Windows” in full, or abbreviate it to “w.”

But they have removed some other guidance:

>>> Instead of abbreviating “Windows” to “un”, you can write it in full or abbreviate it to “woe” or “w”.

plorkyeran|4 years ago

Encountering "woe32" in GNU things was what made me stop writing M$ as a teen. It was so embarrassingly petty that it made me entirely reconsider the idea of insulting nicknames for things I don't like.

na85|4 years ago

GNU has always had that childish tinge to its writings. Chief GNUsance and all that.

Joker_vD|4 years ago

Free as in "free speech", yes.

jjice|4 years ago

Always interesting to see standards across different groups. The kernel is also very interesting, being very strict and having reasoning that not all may agree with, but has proved to work well.

I think C is a beast for standard in general due to it's rogue history. Now when a language like Rust or Go is created, standards are released with the code via formatting tools that enforce consistency (which I'm all for).

The amount of time I've seen C code with inconsistencies within a single file (naming, spacing, you name it) from fellow students back when I was in college was insane.

Enforced code style standards are great, even if I don't agree with them. Go's public vs private distinction is a good example. I really am not a huge fan of the pascal vs camel case to denote private and public (it's grown on me a bit, but still not a fan), but I know their code is going to be reasonable (in looks) because Go is very picky about how the code looks.

asicsp|4 years ago

>In most Unix utilities, “long lines are silently truncated”. This is not acceptable in a GNU utility.

Would be interested to know examples for this.

bigbillheck|4 years ago

Old versions of sort: http://man.cat-v.org/unix_7th/1/sort

Unix utilities in the old days weren't all that great. One example I've posted about here before is how mv would refuse to move files across filesystem boundaries (because it's not a 'move', it's a 'copy and delete', so you had to use cp and rm instead).

c0l0|4 years ago

Just a few weeks ago, I fixed a problem in an internal tool (that still also runs on an ancient Solaris 10 box) by switching from `awk` to `gawk`, since the former would briefly whine on stderr and quit whenever a line in its input would contain too many fields. A recent change had managed to break that undocumented barrier.

In this case there's at least no silent breakage involved, but the badly written shell script that called it did not bother to check for that condition, and a fair number of heads were scratched for a while as a consequence.

astrobe_|4 years ago

The whole paragraph:

> Avoid arbitrary limits on the length or number of any data structure, including file names, lines, files, and symbols, by allocating all data structures dynamically. In most Unix utilities, “long lines are silently truncated”. This is not acceptable in a GNU utility.

... goes against MISRA C, which certainly is preferable in the domain I work, embedded systems - because dynamic allocations all over the place are a recipe for CVEs.

sigzero|4 years ago

I hate that formatting style personally.

pentagone|4 years ago

> First off, I’d suggest printing out a copy of the GNU coding standards, and NOT read it. Burn them, it’s a great symbolic gesture.

- The doc on Linux kernel coding style

junon|4 years ago

Me too. I've never understood it. I just went back through the clang-format documentation and looked at some of the examples for the GNU style and was reminded at how utterly unreadable the resulting code is.

wirrbel|4 years ago

I never worked in a codebase that was formatted in this style and surely its weird and not at all what I am used to. But I somehow from looking at the examples find it to be somewhat pleasant. Doesn't mean I would pick it as my standard but I can see how one could.

I do prefer putting opening braces at the line end in all situations though (but that also rules out a lot of other styles).

musicale|4 years ago

How about "always use gcc/g++ in memory-safe compilation mode?"

I'd like to be able to type something like:

  gcc -march=x86-64-safe my_buggy_server.c
Come to think of it, that should probably be the default.

abakus|4 years ago

I find the coding standard too long to be taken seriously.