如何解决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”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。