I tried to google my question, but given the title I find it hard to formulate properly, so I wasn't able to find anything. So I decided to ask here: why does this compile?
#include <cstdio>
class Test
{
public:
Test(int param = 42)
{
printf("ctor %d\n", param);
_data = param;
}
private:
int _data = 0;
};
class Test2
{
// wtf? v is not yet declared
Test t{ v };
int v = 333;
};
int main()
{
Test2 t2;
// This doesn't compile though.
// Test t{ v };
// int v = 333;
printf("don't optimize 0x%X\n", &t2);
return 0;
}
I expected the compiler to issue an error of "undeclared variable v" or something.
Also, Test constructor always prints 0 even if I declare v const.
Of course, if I rearrange lines like this:
int v = 333;
Test t{ v };
then it works as expected.
As pointed to by @RichardCritten in comment, class scope says (emphasis are mine):
In your case, it's a "in-class brace-or-equal initializers":
A compiler probably has to do two passes in order to process this information.
As for why you are getting zero printed, this is due the order of initialization. All members are initialized in order of declaration - this is the golden rule (no matter whether you are using initializers in the class definition or in a constructor). In your case,
tis initialized beforev.This makes your code contain undefined behavior, since you try to use the value of
vbefore it is initialized.constdoesn't change anything in this case. A const non-static member is still a non-static member. You have to make itconstexpr staticorstatic constto make a difference.