4 ms·
C programmers expect dead code removal. Especially when the compiler also inlines functions (and, of course, inlining makes the biggest impact on short function
by maxlybbert 10y ago
C programmers expect dead code removal. Especially when the compiler also inlines functions (and, of course, inlining makes the biggest impact on short functions; and one way to get short functions is to have aggressive dead code removal). And macros can expand into very weird, but valid, code; so the statement that "nobody would ever write code like that" isn't relevant. The compiler may well have to handle unnatural looking code.
As others have stated, compilers generally don't actually have special case code to create unintuitive behavior if it looks like the programmer goofed.
It's possible and desirable for a compiler to remove branches of "if" statements that it knows at compile time won't ever be true. And, of course, one special case of statically known "if" statements are checks for NULL or not-NULL pointers in cases where the compiler knows that a pointer will never be NULL (e.g., it points to the stack) or will always be NULL (e.g., it was initialized to NULL and passed to a function or macro).
So the standard allows the compiler to say "this pointer cannot be NULL at this point because it was already dereferenced." Either the compiler is right because the pointer couldn't be NULL, or dereferencing the pointer already triggered undefined behavior, in which case unexpected behavior is perfectly acceptable. Some programmers will complain because the compiler won't act sensibly in this case, but C doesn't have any sensible option for what the compiler should do when you dereference a NULL pointer (yes, your operating system may give you a SEGFAULT, but the rules are written by a committee that can't guarantee that there will be an operating system).
- vyodaiken 10y agoC programmers should be able to expect that "optimizations" will not transform program meaning. And because C is so low level, certain types of optimizations may be more difficult or impossible. If the pointer was explicitly set to NULL, the compiler can justifiably deduce the branch will not be taken but the deduction "if the programmer dereferenced the pointer it must not be NULL" is not based on a sound rule. In fact, the whole concept that the compiler can make any transformation it wants in the presence of UB is wacky. Optimization should always be secondary to correctness.
- msbarnett 10y ago> C programmers should be able to expect that "optimizations" will not transform program meaning. If x is null, the program in #2 has no meaning. The only way to preserve its meaning is to assume x is not null. > Optimization should always be secondary to correctness. If x is null, the program in #2 has no correctness. The only way to salvage its correctness is to assume x is not null.
- vyodaiken 10y agoExactly. You are assuming that a poorly written standard is correct and engineering practice of working programs is incorrect.
- msbarnett 10y agoOk, so you want compilers to generate a translation for program #2 that works "correctly" to your mind when x is null. Please explain to the class the meaning of the construct int y = *x; when x is null, so that all conforming C compilers can be updated to generate code for this case "correctly".
- yorwba 10y agoSomething like assert(x); int y = *x; is probably closer to the intended meaning. Checking if(!x) afterwards is still dead code, but at least the program is guaranteed to fail in a defined manner. Of course, if implemented this way, every dereference would have to be paired with an assert call, bringing the performance down to the level of Java. (While bringing the memory safety up to the level of Java.)
- msbarnett 10y agoThat's the opposite of what he wants. He wants a compiler that produces a translation which derefrences the null and follows the true branch. He wants null to equal a valid addressable address, which is completely nonstandard and not portable to everywhere C is used, to be standard that portable compilers emit code for. He wants to imagine that null and zero are the same thing.
- mjevans 10y agoOK, I think I see what SHOULD happen here. It's been forever since I've actually compiled a C program not part of some package I was installing, BUT. * There should be a warning flag, and it should be ON BY DEFAULT, that //all// code removal is stated, and the logic behind it given. * It should be possible to elevate that condition to an error (and that too might even be the default).
- maxlybbert 10y agoI have no idea if it's true, but compiler implementers swear that their compilers perform so many optimizations, and that those optimizations allow additional optimizations, that this kind of approach would bury you in messages.