Undefined behavior is primarily something that that has effects, rather than at compile time. For example, taking the value of an uninitialized local variable.
int main() {
int i;
if(some_big_complicated_function()){
i = 0;
}
printf("%d\n",i);
}
Is this undefined behavior? The compiler can't be sure, because it can't know whether `some_big_complicated_function()` returns true or not.
Therefore, it would need to be a runtime check, rather than a compile time check. But runtime checks are expensive, and so it typically isn't done. It would be entirely allowed by the standard to give such a warning at runtime, but the resulting program would go much, much slower due to all the checks.
What you say is true, but this case could easily trigger a warning about possible use before assignment. The compiler doesn't have (and can't) to prove that either branch will always be taken at runtime. And there's no benefit to code like this anyway, just write it so it's obviously to be assigned. Your coworkers will thank you.
And really, the main benefit to not assigning a value in the declaration is to get the compiler to tell you if there is a code path that misses an assignment.
int i;
if (foo || bar)
i = 1;
else if (baz) {
if (!quux)
goto fail;
i = 2;
}
printf("%d", i); // not all code paths assign a value
That's shoddy programming - it obviously contains an error.
As someone who compiles with "-Wall -Wextra -Werror", I believe that this example program shouldn't even be allowed to compile, even though the standard allows it.
The variable should really be initialized explicitly, which shouldn't be expensive at runtime.
int i = 1; /* or whatever */
Alternately, if the programmer intended to only print when some_big_complicated_function() return true - which is a strong possibility because they only wrote a value to "i" for that case - then the bug is in the position of the printf and possibly the variable definition, if you're using >=C99.
#include <stdlib.h>
#include <stdio.h>
int some_big_complicated_function(void);
int main() {
if (some_big_complicated_function()) {
int i = 0;
printf("%d\n", i);
}
return EXIT_SUCCESS;
}
> the resulting program would go much, much slower due to all the checks.
That depends on a lot. It can be (very) significant if you're talking about the middle of a hot loop; in the given example that runs once per main(), the difference is negligible.
For better examples and a discussion of why it can be very hard to issue useful warnings when optimizing around undefined behavior, see LLVM's series of articles that should is mandatory reading for anybody working with C/C++.
This would certainly worth a warning (at some warning level) exactly because what you say -- the compiler is not sure that the behavior is fully defined.
I wasn't sure whether or not it would print out a warning, so I tested it. With g++ 4.8.4, there is no warning printed, even with `-Wall -Wextra -pedantic`.
Therefore, it would need to be a runtime check, rather than a compile time check. But runtime checks are expensive, and so it typically isn't done. It would be entirely allowed by the standard to give such a warning at runtime, but the resulting program would go much, much slower due to all the checks.