It seems like this program always prints 0. I used the following command line:
clang++ prog.cc -std=c++14 -pedantic-errors
It looks like clang does an unnecessary zero-initialization of x here. Why is that?
#include
struct S { int x; S() { std::cout << x << std::endl; } };
int main() { S s; }
What version of clang, I’ve just tried this with recent revision and it’s printing random values.
It is a case of “undefined value” and will depend on what happens to be on the stack where the struct S is located. This may be the same or different value, depending on a number of factors:
-
Is the stack at the same place every time.
-
What (if anything) has this been used for before you got here…
-
If the code is optimised or not.
-
Processor architecture.
For example, if you have address space randomization turned on, the return address and local variable addresses that may be stored on the stack will vary, where if you haven’t got that, it will be constant. If that part of the stack has NEVER been used, then zero is a likely value, but some runtime environment will fill uninitialized stack locations with other patterns.
And of course, if the code is optimised, it will depend on what registers the value for x ends up in, and what that was holding before - and this of course also depends on the actual processor architecture.
When compiling without optimization it will depend entirely on whatever
happens to be on the stack where the object is allocated, hence on whatever
was left behind by the initialization code that executed before main was
invoked. (If the init code never reached that stack depth, then
consistently getting zero is expected since the stack is zero-initialized
by the OS.)
Example: http://melpon.org/wandbox/permlink/7BlNvpS6Hq34fqTi
Note how the second invocation of foo() prints the value left behind by the
first invocation of foo().
Of course even if it consistently printed zero, that would still not be a
sound way to detect unnecessary zero-initialization, since if it is
uninitialized then the value that is printed is undefined, in which case
consistently printing zero is just as reasonable as any other value. (Also,
even it it *did* perform zero-initialization, this would be inefficient but
not incorrect, hence it doesn't actually make sense to perform this test
without optimization enabled.)