33

Why isn't the output 101 while I assigned the previous x to the new x?

int x = 101;
{
    int x = x;
    std::cout << x << std::endl;
}

Output (garbage):

422634

I thought the second x would be initialized to 101 but it isn't initialized.

Note: The solution in this case is int x = ::x but the question is why it happens.

masoud
  • 55,379
  • 16
  • 141
  • 208
  • 2
    I asked [about something similar](http://stackoverflow.com/questions/14935722/does-initialization-entail-lvalue-to-rvalue-conversion-is-int-x-x-ub) recently... – Kerrek SB Apr 01 '13 at 15:41
  • The latest C++1y draft makes this undefined behavior as well, see [Has C++1y changed with respect to the use of indeterminate values and undefined behavior?](http://stackoverflow.com/questions/23415661/has-c1y-changed-with-respect-to-the-use-of-indeterminate-values-and-undefined). – Shafik Yaghmour May 03 '14 at 02:52

3 Answers3

46

Point of declaration

The point of declaration for a name is immediately after its complete declarator and before its initializer... [C++ Standard § 3.3.2/1]

Compiler completes the declaration when it knows enough about declarator.

Above code is equal to the below one:

int x = 101;
{
  int x;
  x = x; <------------------// Self assignment, assigns an indeterminate value.
  std::cout << x << std::endl;
}

Because, the declaration of inner x completed before = (assignment)

int x = x; <--// Now, we have the new `x` which hides the older one, 
     ^        // so it assigns itself to itself
     |
     +---// Point of declaration,
         // here compiler knows everything to declare `x`.
         // then declares it.

 

On the other hand, when we declaring complex objects, the point of declaration is farther. So, the behavior is different.

For example, below code is OK

const int i = 2;
{
  int i[i];
         ^
         |
         +----// Point of declaration
              // compiler has to reach to "]"
              // therefore before declaring `i` as an array
              // there is just one `i`, the `i` of `const int i=2`
}

In above code, compiler has to know the actual size of the array to complete the declaration, so the point of declaration is ]. Therefore the i within [i] is the outer i because declaration of the i of int i[... isn't completed yet. Thus, it declares an array with 2 elements (int i[2];).

 

Also, this example shows the point of declaration for an enumerator

const int x = 12;
{
  enum { x = x };
               ^
               |
               +---// Point of declaration
                   // compiler has to reach to "}" then
                   // there is just one `x`, the `x` of `const int x=12`

}

The enumerator x is initialized with the value of the constant x, namely 12.

masoud
  • 55,379
  • 16
  • 141
  • 208
  • Maybe we can add that the declaration is also complete when using the c++11 `auto` keyword, and furthermore it's an error to do `auto x = x` – Jaffa Oct 02 '13 at 08:01
  • @Geoffroy: I've made a question about `auto x=x;` [here](http://stackoverflow.com/q/19133452/952747) – masoud Oct 02 '13 at 11:26
  • What would be the point of declaration, when using direct initializers? (e.g. int x(x)). The Microsoft Visual C++ Compiler (MSVC 2017) seems to put the point of declaration at the closing parens. – Tom May 14 '18 at 20:55
  • @deepmax If you are right, then GCC has an issue, because "int i(i)" compiles without any global "i" defined. (only warning, that i is uninitialized) – Tom May 15 '18 at 17:47
  • @Tom: Umm, let me change my opinion, If `int i(i);` is like `int i = i;` then then MSVC is wrong. Isn't it? – masoud May 19 '18 at 07:41
  • @deepmax `int i(i);` is like `int i = i;` in GCC. In MSVC `int i(i);` does not compile without global `i` defined. – Tom Jun 01 '18 at 19:59
9

There's another way to do it.

#include <iostream>
int x = 101;
int main()
{
  int x = ::x;
  std::cout << x << std::endl;
  std::cin.get();
}
greego
  • 105
  • 3
  • 4
    Right, but the question is asking about _why_, not _how to solve it_. – masoud Apr 01 '13 at 17:00
  • 2
    @MM The question is *"Why is the output not 101 if I assigned the previous x to the new x?"* - this answer can be seen as answering the question in the sense of: *"because you haven't qualified the name as follows:"*. It's a worthwhile answer IMO, along with your one (which is also a great answer). – JBentley Apr 23 '13 at 18:19
0

variable scope In front of x will be overwritten. int x = x; This one there are two processes. One: int x;(define variable x and allocate memory and specify the initial value : x = 0); this moment , the front x will be hidden. Two: x = x;(Do not find the value x);

chuang wang
  • 65
  • 1
  • 6