* Changes that replace undefined behaviours with undefined values. This makes it easier to catch certain types of coding errors at the cost of certain kinds of optimizations.
I'm comfortable with the first kind, although you can already achieve something very similar to that with most compiler (as far as I know) by building with optimizations disabled. Also stuff like missing return values generates a warning in any compiler worth using, if you ignore that kind of warnings you can only blame yourself.
The 2nd kind bothers me more, because it makes otherwise invalid C code valid in this dialect. I'm worried this makes things even more difficult to explain to beginners (and not so beginners, I still have to check the aliasing rules from time to time to make sure the code I'm writing is valid).
Even if you're very optimistic this friendly C is not going to replace daddy anytime soon. There'll be plenty of C code out there, plenty of C toolchains, plenty of C environment where the definition of friendliness is having a dump of the registers and stack on the UART in case of an error. Plenty of environments where memcpy is actually memcpy, not memmove.
For that reason I'd be much more in favour of advocating the use of more modern alternatives to C (and there are a bunch of those) rather than risking blurring the lines some more about what is and isn't undefined behaviour in C.
Precisely. The idea here is that any C program that does not specifically require one's complement or sign-magnitude representation will work just as well compiled as friendly C as it does compiled as C.
Also, just because testing has found no exploitable bugs in a C program compiled with GCC 4.8 does not mean that GCC 4.9 will not introduce a new optimization that wreaks havoc with undefined behavior that was there all along. No such surprises with friendly C. It's the trusty C compiler that you had in 1995, and it always will be.
Security-critical programs would never rely on undefined behavior!, you might say. Let us take the example of ntpd, one of the building blocks of the Internet, considered critical enough to be part of two Google bounty programs. Here is a list of currently harmless undefined behaviors in it that a compiler could use as an excuse to produce vulnerable binary code tomorrow: http://bugs.ntp.org/buglist.cgi?emailreporter1=1&emailtype1=...
Friendly C is not a new language. It is C as most developers understand it, and with bad surprises prohibited as much as possible.
Disclaimer: Julien, who reported these ntpd undefined behaviors, is my colleague, and I am a co-author of the “friendly C” proposal.
I get your point (and it's a fair one) but what happens when it goes the other way? A bit of code written (and working) in friendly C finds its way into a regular good old C codebase. Suddenly it contains a critical bug that may go unnoticed.
Or some coder is used to friendly C, uses aliasing, memcpy and wrapping arithmetic without thinking twice. Then he's asked to work on some project building with a regular C toolchain. Gun is cocked and pointed at the foot.
Those problems only occur because friendly C is a dialect of C, you don't get those drawbacks if you tell devs to use Rust or whatnot, because the difference between Rust and C is obvious, unlike friendly C and C.
This exact problem exists today if someone takes code from the Linux kernel that is compiled with things like -fno-strict-aliasing. Undefined Behaviour makes programs unpredictable in the first place, given that you can't reasonably ensure you're not triggering it. I would expect a lot more people to use friendly-c (or simple-c or yes-this-is-how-your-cpu-works-c) than standard c.
As he notes, people who need the undefined behaviour-induced optimisations are in the minority.
Such code would also fail if passed to tools like lint, and would result in warnings or worse when loaded in IDEs. The incredible C toolchain built over the decades is one of C's biggest advantages; friendly-c cannot afford to lose even 10% of it.
The security critical programs I've worked on, nobody would even think of randomly upgrading the compiler just because a new version happens to be available.
But take OpenSSL as an example of a critical security program. Nothing in the usage practice suggests not upgrading the compiler, or even going to the next version of libc.
Many open-source programs can be security-critical (any network-facing daemon, for instance), and there's nothing which ties them to a specific compiler.
I usually hear the latter type of system described as "safety-critical" or "life-critical". You're right that it's an entirely different world, though.
* Changes that replace undefined behaviours with undefined values. This makes it easier to catch certain types of coding errors at the cost of certain kinds of optimizations.
* Changes that remove undefined behaviours (wrapping arithmetic, memcpy/memmove, aliasing rules).
I'm comfortable with the first kind, although you can already achieve something very similar to that with most compiler (as far as I know) by building with optimizations disabled. Also stuff like missing return values generates a warning in any compiler worth using, if you ignore that kind of warnings you can only blame yourself.
The 2nd kind bothers me more, because it makes otherwise invalid C code valid in this dialect. I'm worried this makes things even more difficult to explain to beginners (and not so beginners, I still have to check the aliasing rules from time to time to make sure the code I'm writing is valid).
Even if you're very optimistic this friendly C is not going to replace daddy anytime soon. There'll be plenty of C code out there, plenty of C toolchains, plenty of C environment where the definition of friendliness is having a dump of the registers and stack on the UART in case of an error. Plenty of environments where memcpy is actually memcpy, not memmove.
For that reason I'd be much more in favour of advocating the use of more modern alternatives to C (and there are a bunch of those) rather than risking blurring the lines some more about what is and isn't undefined behaviour in C.