簡體   English   中英

使用 g++ 進行奇怪的零初始化

[英]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;
}

我手動執行了從functionx (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.

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