簡體   English   中英

int foo = foo 的標准參考

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM