13

Consider following code example:

#include <iostream>

static int bar = bar;

int main()
{
    int foo = foo;
    std::cout << "foo = " << foo << std::endl;
    std::cout << "bar = " << bar << std::endl;
}

I get following compiler warning:

main.cpp: In function 'int main()':
main.cpp:7:15: warning: 'foo' is used uninitialized in this function [-Wuninitialized]
     int foo = foo;
               ^

Output:

foo = 0
bar = 0

I expected this warning as foo is used unitialised. Instead of 0, 'foo' can be anything. Self-assignment is undefined.

But why is the the self-assignment of 'bar' not warned? Is this assignment of 'bar' defined or undefined behaviour and why?

I know, static variables of elementar data types are initialised with '0' but in this case, the variable 'bar' is used during its initialisation. I'm wondering, if this is defined behaviour and the '0' is the expected output. (Which would explain, that no compiler warning occurs).

Link to Live example

meddle0106
  • 1,292
  • 1
  • 11
  • 22
  • Static initialization has more than one phase. – chris Apr 10 '14 at 14:52
  • Probably because static variables in the global scope are always zero-initialized, so the compiler knows `bar` is effectively `0` before the assignment. – Frédéric Hamidi Apr 10 '14 at 14:55
  • 1
    @FrédéricHamidi: Note that they are not zero-initialized, but default-constructed. That makes a difference for structs/classes! – anderas Apr 10 '14 at 14:58
  • @anderas, true, I should have said static *primitives* :) – Frédéric Hamidi Apr 10 '14 at 14:59
  • 2
    @anderas AFAIK, static-storage-duration things *are* zero-initialised before any other initialisation takes place, including potential later execution of a default ctor. – Angew is no longer proud of SO Apr 10 '14 at 16:05
  • @anderas [basic.start.init#2](https://timsong-cpp.github.io/cppwp/n3337/basic.start.init#2): _"**Variables with static storage duration** ([basic.stc.static]) [...] shall be zero-initialized ([dcl.init]) before any other initialization takes place."_ – rosshjb Nov 19 '21 at 17:18

1 Answers1

15

I believe that part of the standard is relevant to your question (§3.6.2/2):

Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.[...]

So in this case, even before the compiler looks at your definition of bar, it has already zero-initialized it.

As it is specified a bit further in the standard, there shall be two phases for static variables initialization (emphasis mine).

Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.

JBL
  • 12,588
  • 4
  • 53
  • 84