[英]Strange zero initialization with g++
在使用 g++ 4.4.3 進行整數初始化時,我遇到了以下代碼的奇怪行為。
int main()
{
int x(int());
int y = int();
cout << x << " " << y << endl;
}
結果是:
1 0
“y”的值如預期的那樣是 0,但 x 的值卻是奇怪的“1”!
在 VS2008 上產生以下鏈接錯誤(一個 function 聲明,但沒有定義):
unresolved external symbol "int __cdecl x(int (__cdecl*)(void))"
誰能解釋 g++ 的這種奇怪行為?
int x(int());
被解析為 function 聲明。
它聲明了一個名為x
的 function ,返回一個int
並接受一個參數,其類型為 function 返回一個int
並且不接受 arguments。
這被稱為最令人煩惱的解析。
為了補充GMan的答案( x
是 function 定義),為什么1
。
The reason for the output to be 1
is that at the place of call std::cout << x
, the function decays into a pointer to the function (the language does not allow you to pass functions as arguments to other functions, so as使用 arrays 執行到指向指針的隱式轉換)。 現在,沒有采用 function 指針的ostream
的重載,並且編譯器嘗試將 select 轉換為任何可用的重載。 此時它發現最好的轉換序列是bool
並打印1
(指針不是 0)。
您可以通過更改行為來檢查這一點,您可以使用std::cout << std::boolalpha << x
,這將打印true
而不是1
。 另外,有趣的是,VS 是正確的,因為表達式std::cout << x
需要獲取x
的地址,然后使用function 並且如果沒有定義該程序是不正確的即 function。 您可以通過提供定義再次檢查:
int f() {}
int main() {
int x(int()); // 1
x( &f ); // 2
}
int x( int(*)() ) { // 3
std::cout << "In x" << std::endl;
}
我手動執行了從function
到x
(1) 定義中的pointer-to-function
的轉換以及帶有參數f
(2) 的調用——注意 1 中的聲明和 3中的定義是相同的簽名,並且如果您不這樣做,編譯器將執行x( &f )
中的&
。
只需添加更多括號:
int main()
{
int x((int()));
int y = int();
cout << x << " " << y << endl;
}
現在 x 是一個 int,而不是 function。
正如其他人所說, x
是 function 聲明。 Since there is no predefined ostream inserter defined for function pointer types, g++ appears to using the implicit bool conversion (used for checking if a function pointer is NULL) to find a way to output it.
另一方面,Visual C++ 抱怨聲明的 function x
從未定義,因此無法完成鏈接。 我懷疑 g++ 在這種情況下足夠聰明,可以看到 function 從未被調用,因此不必擔心鏈接。
您可以嘗試添加 function int x(int(*)()) { return 0xdeadbeef; }
的虛擬定義。 int x(int(*)()) { return 0xdeadbeef; }
到代碼中,然后看看 MSVC 對它做了什么。
C++ 將第一個解釋為 function 的聲明。
這個
int x(int());
實際上是一個 function 聲明輸入是一個 function 的以下簽名
int fn(void)
傳遞給std::cout <<
的 function 指針被轉換為 bool(1),因為它是一個非 NULL 指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.