Why does the following compile without an error?:
int main()
{
int x = x; //I thought this should cause an error
return 0;
}
Where in the standards is it explained why this is allowed?
This question has a slightly different answer in C than in C++.
In both cases, int x = x;
tries to initialize x
with itself.
In C++: [dcl.init]/12 (N3936) says that any evaluation of an object with indeterminate value causes undefined behaviour, except for certain cases involving unsigned char
. In fact there is an Example:
int f(bool b) {
unsigned char c;
unsigned char d = c; // OK, d has an indeterminate value
int e = d; // undefined behavior
return b ? d : 0; // undefined behavior if b is true
}
In C: It is more complicated. This is very similar to the behaviour of int b; foo(b - b);
which is covered in full here.
I won't repeat that text but the conclusions are, in C11:
int a = a; &a;
causes UB if and only if the system has trap representations for int
int a = a;
, with no subsequent occurrence of &a
, causes UB.Historical note: In C90 this caused UB. In C99 the trap representation was introduced, and in C11 the possibility of register trap was introduced (for Itanium). The C++ standard doesn't deal with trap representations at all, it seems underspecified in the case of things like bitwise operators generating negative zero.
The answer for C++ - I am quoting C++11 standard:
3.3.3.1:
A name declared in a block (6.3) is local to that block; it has block scope. Its potential scope begins at its point of declaration (3.3.2) and ends at the end of its block.
And the point of declaration is defined in 3.3.2 as
The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below.
[ Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value. — end example ]
Obviously, using the value of x
before it is initialised is undefined behaviour.
C++14 draft N4140 [basic.scope.pdecl]/1:
The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:
unsigned char x = 12;
{ unsigned char x = x; }
Here the second
x
is initialized with its own (indeterminate) value. —end example ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With