繁体   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