On Wed, 27 May 2020, Greg A. Woods wrote:
Sadly most compilers, including GCC and Clang/LLVM
will, at best, warn
(and warnings are only treated as errors by the most macho|wise); and
compilers only do that now because they've been getting flack from
developers whenever the optimizer does something unexpected.
Don't talk to me about optimisers... That's not the code that I wrote!
I've seen code simply disappear, because the "optimiser" though that it
was cleverer than I was.
The Linux kernel example I've referred to
involved dereferencing a
pointer to do an assignment in a local variable definition, then a few
lines later testing if the pointer was NULL before using the local
variable. Unoptimised the code will dereference a NULL pointer and load
junk from location zero into the variable (because it's kernel code),
then the NULL test will trigger and all will be good. The optimizer
rips out the NULL check because "obviously" the programmer has assumed
the pointer is always a valid non-NULL pointer since they've explicitly
dereferenced it before checking it and they wouldn't want to waste even
a single jump-on-zero instruction checking it again. (It's also quite
possible the code was written "correctly" at first, then someone mushed
all the variable initialisations up onto their definitions.)
Typical Penguin/OS behaviour...
In any case there's now a GCC option:
(to go along with -fno-strict-aliasing and -fno-strict-overflow, and
-fno-strict-enums, all of which MUST be used, and sometimes
-fno-strict-volatile-bitfields too, on all legacy code that you don't
want to break)
I'm sure that there's a competition somewhere, to see who can come with
GCC's -fmost-longest-and-most-obscure-option flags...
It's even worse when you have to write bare-metal
code that must
explictly dereference a NULL pointer (a not-so-real example: you want
to use location zero in the CPU zero-page (e.g. on a 6502 or 6800, or
PDP-8, etc.) as a pointer) -- it is now impossible to do that in strict
Standard C even though trivially it "should just work" despite the silly
rules. As far as I can tell it always did just work in "plain old" C.
I've programmed a PDP-8! 'Twas way back in high school, and I found a bug
in my mentor's program; it controlled traffic lights...
The crazy thing about modern optimizers is that
they're way more
persistent and often somewhat more clever than your average programmer.
They follow all the paths. They apply all the rules at every turn.