Hacker News new | ask | show | jobs
by CJefferson 2121 days ago
I've currently involved with a system, written in C, which has been going for 30 years: GAP - https://www.gap-system.org

While I write a lot of C, I immediately disagree with the idea that C has a "simple (yet expressive) abstract machine model". Every so often we find a bug which has been present for over a decade, because some new compiler has added a (perfectly legal by the standard) optimisation which breaks some old code.

Picking one example: in the "old days", it was very common (and important for efficiency) to freely cast memory between char, int, double, etc. For many years this was fine, then all compilers started keeping better track of aliasing and lots of old code broke.

Also, while POSIX is a nice base, it stops you using Windows, and also almost every non-trivial program ends up with a bunch of autoconf (which has to be updated every so often) to handle differences between linux/BSD/Mac.

Also, definatly don't distribute code where you use flags like '-pedantic', as it can lead to your code breaking on future compilers which tighten up the rules.

4 comments

Oh I had a fun one like this just this morning. I have (C++) code spanning back to the early 1990's, although some of it was written (as C) a decade before that. It relies on checking the floating point unit status register for a bunch of its error checking. Turns out that at some point, casts from floating point to integer types started being implemented (by the compiler) using the cvttss2si instruction. And when the floating point value is too large to be represented in the integer, the fpu flag is set to 'invalid'. Which (I assume, from how everything else was implemented) didn't used to happen with whatever instruction(s) were used before SSE. And in my code, this only happens very rarely (basically it needs a combination of rare, rare and very rare circumstances to happen - too tedious to explain, not that anyone cares) so I only got bitten by this this week - probably 15 years after this started happening? And yeah the case is technically undefined behaviour, not that I'm enough of a language lawyer to know. If it hadn't been for some kind soul on SO to point this out I wouldn't even have looked in this direction because the last time this combination happened, it worked (and yeah it turns out that that program where 'it works' was compiled 20 years ago...)

Ugh, just venting, but it helps to know that there are others out there suffering through this :)

The changing meanings of compiler flags are a personal pet-peeve, as it leads to strange situations where you have to add both "-Wall" AND "-Wextra".

Still in programs that I expect to be used on wildly different systems I tend to enable all the flags that are common in the development-builds, and be more conservative in the production/deployed version.

> Also, while POSIX is a nice base, it stops you using Windows, and also almost every non-trivial program ends up with a bunch of autoconf (which has to be updated every so often) to handle differences between linux/BSD/Mac.

I agree the lack of compliant POSIX on Windows is annoying. However, unless you rely on 3rd-party libraries, you can use #ifdef to write OS-specific code without autoconf.

-pedantic only enables warnings, it cannot change the meaning of code; not even on newer compilers.
Right, but that's not the concern.

You compile your code with -pedantic, it works, and then you distribute the source. A user gets that code, compiles it, it works, and they integrate it into their product. Later, that user upgrades or changes their compiler and your code doesn't build anymore because there's a new warning. Now they have to patch your build.

You are right, I mis-remembered what the flag did, sorry.

I've seen projects with -pedantics -Werror, which are particularly annoying (-Werror in general to be honest, I understand why people might want it for CI of course).

I like using -Wall -Wextra -Werror for code under my control, but I would disable that flag if distributed as a library to others.