Zero size objects
tedunangst.com
tedunangst.com
This article, in a nutshell, points out that memcpy and friends have a similar property: Although code may ask memcpy to copy 0 bytes (which will not crash in practice if argument pointers are invalid or NULL), behavior is still undefined if the argument pointers source/destination are invalid.
I think the article is missing an introduction, as I had no idea initially what kind of "difference" between the pointer/length pairs the author was asking about.
I think it really was a defect in the C standard to not specify behavior of calls like memcpy(NULL, NULL, 0) It has obvious no-op semantics, and every implementation I've ever seen would accept it just fine. I bet there is a lot of code out there that assumes that memcpy() and friends work in this "traditional" way.
For memcpy it's never safe for it to access the byte at "src+len" (it could be past the end of mapped memory) nor is it safe to write to "dest+len" So if len==0 it should follow that it won't access either src[0] or dest[0].
The spec basically allows len==0 to be a special case for this rule, although it's not clear what implementation would ever be able to take advantage of that.
Technically correct is not a useful standard. Working code is. If compilers make code like this fail, it should fail very loudly, not quietly; silently eliminating null checks is not a virtue unless it is absolutely known that the null pointer use would definitely blow up otherwise. Which is not always guaranteed in practice, as the memset experiment here shows.
If compiler authors really want to pursue this optimization, elimination of dead code by means of detection of undefined code should result in a compilation error, because the code intent is self-contradictory.
Those optimizations can be used to quickly throw out unnecessary code like null-pointer checks inside inlined functions, so they are valuable and good to have.
So it's a matter of how much energy you spend on diagnostics, which ends up a rather heuristic field and perhaps we'd just be better off focusing on better static analysis tools that are separate from or can otherwise be decoupled from compilers.
The gain from application of an optimization needs to be compared with the time and cost of bugs introduced by the same optimization. And dead code elimination isn't necessarily a huge win - if you're fairly sure code is dead, you can make it cheap at the cost of being more expensive should it actually be alive (see my other comment).
And of course, the standards committee should get off their asses and define some behaviors.
I believe this analysis is possible; taint the control flow analysis with a flag. Macro expansion and inlined functions are also not intractable; debug information requires tracking token location information all the way through to generated code, so this information can be used to apply a heuristic.
Dead branches don't need to cost that much, BTW. Put the code for disfavoured basic blocks out of line with other code (so it doesn't burn up code cache), and use hinted conditional jumps to enter them (e.g. on x86, forward conditional jumps are predicted not to be taken).
Ditto, if you have an explicit block (i.e. no macros / etc) that always causes undefined behavior, warn or throw an error by default.
Not everything the standard permits is in fact a good idea.
Though I'm not sure current SMT solvers are up to the task. (Related: I was using Sugar for something a while back, only to find it was spitting out weird error messages. Turns out it encodes integers as <size of domain> boolean variables, which doesn't work particularly well for large domains - it was hitting a 4 (2?) GB limit on the size of the temporary SAT input file and choking)
http://blog.regehr.org/archives/1180
According to the article, OpenBSD changes how GCC's optimization options get enabled with global `-Ox` options, so OpenBSD has a “Friendly C” compiler of sort.
How 'big' is zero? Can zero be quantified? If it can, then how come zero divided by is zero, but anything divided by zero is undefined?
I think it is time for another trip out west, California, baby!