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

Sla*_*nov 20 c++ gcc g++

我遇到了以下代码的奇怪行为,同时使用g ++ 4.4.3进行初始化.

  int main()

    {

        int x(int());

        int y = int();

        cout << x << "  " << y <<  endl;
    }
Run Code Online (Sandbox Code Playgroud)

结果是:

1 0

"y"的值如预期的那样为0,但x的值奇怪地为"1"!

在VS2008上产生以下链接错误(函数声明,但没有定义):

unresolved external symbol "int __cdecl x(int (__cdecl*)(void))"
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释这个奇怪的g ++行为吗?

GMa*_*ckG 24

int x(int()); 被解析为函数声明.

它声明了一个名为的函数x,返回int并接受一个参数,该参数具有返回int并且不接受任何参数的函数类型.

这被称为最令人烦恼的解析.


Dav*_*eas 13

为了补充GMAN的答案在这里(x是一个函数的定义),为什么1.

输出的原因1是在调用位置std::cout << x,函数衰减成指向函数的指针(该语言不允许您将函数作为参数传递给其他函数,因此对于数组,隐式转换为指针 -到执行).现在,没有ostream带有函数指针的重载,编译器尝试选择转换为任何可用的重载.此时它发现最佳转换序列是bool和它打印1(指针不是0).

您可以通过更改行为来检查这一点,您可以使用std::cout << std::boolalpha << x,而true不是打印1.而且,有趣的是,VS是与这个权利,因为表达std::cout << x需要考虑的地址x,然后是函数使用,并形成不良的程序,如果没有该功能没有定义.您可以通过提供定义再次检查:

int f() {}
int main() {
   int x(int());      // 1
   x( &f );           // 2
}
int x( int(*)() ) {   // 3
   std::cout << "In x" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我在哪里已经手动执行的转换从functionpointer-to-function的定义中x(1),并用参数中的呼叫f(2) -注,在1的声明和3中的定义相同的签名,并且该&x( &f )将被执行由编译器,如果你不这样做.