[英]Standard reference for int foo = foo
int foo = foo;
編譯。 C++ 標准的哪一部分允許這樣做?
3.3.1 聲明點[basic.scope.pdecl]
名稱的聲明點緊接在其完整聲明符之后(第 8 條)和初始化器之前(如果有),
如果聲明位於文件 scope 中,則該行為已明確定義。 如果您在 function scope 有聲明,並且如果您稍后使用foo
[在這種情況下將初始化為某個未指定的值],則行為將是未定義的。
這個?
int main() {
int foo = foo;
}
object foo
在=
之后確實存在,根據[basic.scope.pdecl]
:
名稱的聲明點緊跟在它的完整聲明符(第 8 條)之后和它的初始化器(如果有的話)之前。
但是,整個程序是未定義的,因為您使用(在 RHS 上)未初始化的值:
int x = x;
這里 [..]x
用它自己的(不確定的)值初始化。
和:
盡管標准“推斷和錯誤指定”,但在 RHS 表達式foo
上執行了左值到右值的轉換。
和( [conv.lval]
):
非函數、非數組類型 T 的左值 (3.10) 可以轉換為右值。 如果 T 是不完整類型,則需要這種轉換的程序是非良構的。 If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.
有了適當的警告級別,您就會被告知; 但是,允許編譯調用未定義行為的程序。 當你運行它們時,它們可以做任何事情。
或者,這個呢?
int foo = foo;
int main() {}
請注意, foo
是一個“全局”。 根據[basic.start.init]
,第一步將這些初始化為零:
在進行任何其他初始化之前,具有 static 存儲持續時間 (3.7.1) 的對象應進行零初始化 (8.5)。
所以你會得到一個值為 0 的int foo
; 在這一點上,根據上面的[basic.scope.pdecl]
和[stmt.decl]
stmt.decl],它是有效的:
所有具有 static 存儲持續時間 (3.7.1) 的本地對象的零初始化 (8.5) 在任何其他初始化發生之前執行。 [..]
然后將其值初始化為foo
(本身),即 0。
這是明確定義的......如果有點神秘。
為了徹底起見,這里是第三種也是最后一種情況:
int foo = 42;
int main() {
int foo = foo;
}
可悲的是,這與第一種情況相同。 由於本地foo
已經聲明並且在初始化器被評估時在 scope 中,初始化器使用本地foo
並且您仍然堅持未定義的行為。 不使用全局foo
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.