int foo = foo的标准参考

问题描述

|
int foo = foo;
编译。 C ++标准的哪一部分允许这样做?     

解决方法

           3.3.1声明点[basic.scope.pdecl]      名称的声明点紧接在其完整的声明器(第8节)之后,在其初始化器(如果有)之前, 如果声明在文件作用域内,则行为定义良好。如果在函数作用域中有声明,并且以后使用[1](在这种情况下将初始化为某些未指定的值),则行为将是不确定的。     ,        这个?
int main() {
  int foo = foo;
}
根据
[basic.scope.pdecl]
,对象
foo
确实存在于
=
之后:   名称的声明点紧接在其完整的声明器(第8节)之后,在其初始化器(如果有)之前。 但是,整个程序是未定义的,因为您使用(在RHS上)未初始化的值:   
int x = x;
  在此[..]
x
用其自己的(不确定的)值初始化。 和: 尽管按照标准“推断并指定不正确”,但是对RHS表达式
foo
进行了左值到右值转换。 和(
[conv.lval]
):   非函数的左值(3.10),   非数组类型T可以转换为   一个右值。如果T是不完整的类型,   一个程序需要   转换格式错误。如果   左值引用的对象是   不是T类型的对象,也不是   从T派生的类型的对象,或者   该对象未初始化,一个程序   因此必须进行这种转换   未定义的行为。 有了适当的警告等级,您会得到通知。但是,允许编译调用未定义行为的程序。当您运行它们时,它们什么也做不了。 还是呢?
int foo = foo;    
int main() {}
请注意,
foo
是\“ global \”。根据
[basic.start.init]
,将它们初始化为零是第一步:   具有静态存储持续时间(3.7.1)的对象应在进行任何其他初始化之前进行零初始化(8.5)。 因此,您将得到一个值为0的
int foo
;根据以上
[basic.scope.pdecl]
[stmt.decl]
的规定,这是有效的:   全部零初始化(8.5)   具有静态存储的本地对象   持续时间(3.7.1)在执行之前   任何其他初始化都会发生。 [..] 然后将其值初始化为
foo
(本身),即0。 这是明确定义的...如果有点神秘。 为了彻底,这是第三种也是最后一种情况:
int foo = 42;
int main() {
   int foo = foo;
}
可悲的是,这与第一种情况相同。由于在评估初始值设定项时已经声明了局部
foo
,并且其作用域在范围内,因此初始值设定项使用局部
foo
,您仍然会陷入未定义的行为。不使用全局“ 1”。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...