C++中的声明点

mas*_*oud 33 c++

101当我将之前的内容分配x给新的时,为什么不输出x

int x = 101;
{
    int x = x;
    std::cout << x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出(垃圾):

422634

我认为第二个x将初始化为101 但它没有初始化.

注意:在这种情况下的解决方案是int x = ::x但问题是它发生的原因.

mas*_*oud 45

宣言点

名称的声明点紧跟在完整的声明符之后和初始化之前...... [C++标准§3.3.2/ 1]

编译器在完全了解声明器时完成声明.

以上代码等于以下代码:

int x = 101;
{
  int x;
  x = x; <------------------// Self assignment, assigns an indeterminate value.
  std::cout << x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

因为,内部的声明x完成之前=(赋值)

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.
Run Code Online (Sandbox Code Playgroud)

 

另一方面,当我们声明复杂的对象时,声明点就更远了.所以,行为是不同的.

例如,下面的代码就可以了

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`
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,编译器必须知道数组的实际大小才能完成声明,所以声明点就是].因此,i[i]是外i,因为声明iint i[...尚未完成.因此,它声明了一个带有2elements(int i[2];)的数组.

 

此外,此示例显示了枚举器的声明点

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`

}
Run Code Online (Sandbox Code Playgroud)

枚举器用x常量的值初始化x,即12.


小智 9

还有另一种方法可以做到这一点.

#include <iostream>
int x = 101;
int main()
{
  int x = ::x;
  std::cout << x << std::endl;
  std::cin.get();
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,但问题是询问_why_,而不是_how解决它_. (4认同)
  • @MM问题是*"如果我将前一个x分配给新的x,为什么输出不是101?"* - 这个答案可以被视为回答以下问题:*"因为你没有资格名称如下:"*.这是一个值得回答的IMO,以及你的一个(这也是一个很好的答案). (2认同)