Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a variable be used while being declared?

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?

like image 418
Abo-Mahmoud Al-Homsi Avatar asked Apr 08 '15 21:04

Abo-Mahmoud Al-Homsi


3 Answers

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.

like image 134
M.M Avatar answered Oct 01 '22 19:10

M.M


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.

like image 28
Wojtek Surowka Avatar answered Oct 01 '22 19:10

Wojtek Surowka


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 ]

like image 22
Anton Savin Avatar answered Oct 01 '22 18:10

Anton Savin