I work in Windows 7, the environment Code :: Blocks 16.01, the recommended version of their MinGW default version.

There are some very similar code examples:

#include <iostream> void bar() { int a; std::cout << &a << std::endl; return; } void foo() { int a = 3; std::cout << &a << std::endl; return; } int main() { foo(); bar(); return 0; } 

The displayed addresses on my machine match 100% of the time, and this is quite understandable behavior.

 #include <iostream> void bar() { int a; std::cout << a << std::endl; return; } void foo() { int a = 3; std::cout << a << std::endl; return; } int main() { foo(); bar(); return 0; } 

And here the oddities begin. If any optimization is enabled, it displays:

3

0

and if you remove them, it displays:

3

3

In this code example:

 #include <iostream> void bar() { int a; std::cout << a << " " << &a << std::endl; return; } void foo() { int a = 3; std::cout << a << " " << &a << std::endl; return; } int main() { foo(); bar(); return 0; } 

3 <address>

3 <address>

always displayed, regardless of optimization flags.

Why does the inclusion of optimization flags so selectively affect the auto-nulling of variables?

By the way, when using g ++ from under Ubuntu 14.04, similar results were obtained.

    3 answers 3

    This is UB. This code has the full right to format your hard disk or start a nuclear war.

    • And for what a minus? This is true and UB, and rely on the fact that "well, some value will be there" is simply wrong. - VladD
    • @VladD, no one denies UB. However, I ask you to clarify the second part of your statement. - hunter
    • @hunter: Well, in the presence of UB, the argument that there is a variable and its value is incorrect, the standard in this case does not guarantee anything at all . - VladD
    • @hunter can compile a compiler that, when trying to access such a variable, will format the hard disk, and this will not contradict the C ++ standard. - D-side
    • @ D-side, yes, and something like that already happened. - hunter

    As far as I know, there are no auto-zeroing variables in C / C ++ standards, and non-initialized variables store the value that was contained in the memory cell before the variable was declared. The fact that there are stored zeros can be the result of resetting the memory at the completion of the previous program that occupies this chunk of memory. It is possible that the compiler optimizer is engaged in zeroing variables. However, it is good practice to initialize all variables immediately when they are created, and the absence thereof does not guarantee any auto-initialization.

    • "It is possible that the compiler optimizer is engaged in zeroing variables." - why did he reset variables in the second case, but not in the third? - hunter
    • 2
      @hunter, apparently, the compiler had his own reasons. In this case, you should not rely on a specific behavior, but simply always explicitly initialize the variables. - insolor

    This behavior of the optimizer is due to the fact that in the first case the variable is not used and it can be deleted, and in the third case its address is needed and the variable cannot be deleted.

    • This is not a good explanation. In the presence of UB, the compiler had the right to remove both variables and the address. And the more advanced the optimizer is with your compiler, the more willing it will be to “break” the code by finding UB. The fact that he did not do this in this case is an accident not guaranteed. - VladD
    • @VladD, Thanks, I already saw this example in the comments on Habré. I think that the behavior of the same versions of the compiler on the same code examples and the same platforms will still be the same. This randomness is not introduced by the language (because we have UB here), but by the compiler itself. In this question, I needed to get an explanation of the behavior of the compiler with UB (that is, when the standard says nothing), and this explanation (not mine) is the only thing I could get. - hunter
    • The fact of the matter is that depending on anything (the order of functions in the program, the length of the lines, the current date, ...), the result has the right to differ, since all this may indirectly affect the decisions made by the optimizer. Only the compiler developers can give you a guarantee like “if there is an address taking, you can safely not initialize the variable”. - VladD
    • Yes, and the assumption that in the compiled code each function exists in a single copy (and therefore, two function calls will have the same behavior) is incorrect. Think for yourself why. - VladD