简体   繁体   English

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

[英]Strange zero initialization with g++

I came across on a strange behavior of the following code, while playing around with initialization of ints using g++ 4.4.3.在使用 g++ 4.4.3 进行整数初始化时,我遇到了以下代码的奇怪行为。

  int main()

    {

        int x(int());

        int y = int();

        cout << x << "  " << y <<  endl;
    }

the result is:结果是:

1 0 1 0

The value of "y" is 0 as expected, but the value of x is strangely "1"! “y”的值如预期的那样是 0,但 x 的值却是奇怪的“1”!

On VS2008 yields the following link error (a function declaration, but without definition):在 VS2008 上产生以下链接错误(一个 function 声明,但没有定义):

unresolved external symbol "int __cdecl x(int (__cdecl*)(void))"

Can anyone explain this strange behavior of g++?谁能解释 g++ 的这种奇怪行为?

int x(int()); is parsed as function declaration.被解析为 function 声明。

It declares a function named x , returning an int and accepting one parameter, which has the type of a function returning an int and accepting no arguments.它声明了一个名为x的 function ,返回一个int并接受一个参数,其类型为 function 返回一个int并且不接受 arguments。

This is known as the most vexing parse.这被称为最令人烦恼的解析。

To complement GMan's answer here ( x is a function definition) as to why the 1 .为了补充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 with arrays an implicit conversion to pointer-to is performed). 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 执行到指向指针的隐式转换)。 Now, there is no overload of an ostream that takes a function pointer, and the compiler tries to select a conversion to any of the available overloads.现在,没有采用 function 指针的ostream的重载,并且编译器尝试将 select 转换为任何可用的重载。 At that point it finds that the best conversion sequence is to bool and it prints 1 (the pointer is not 0).此时它发现最好的转换序列是bool并打印1 (指针不是 0)。

You can check this by changing the behavior, you can use std::cout << std::boolalpha << x , and that will print true instead of 1 .您可以通过更改行为来检查这一点,您可以使用std::cout << std::boolalpha << x ,这将打印true而不是1 Also, it is interesting to note that VS is right with this one, as the expression std::cout << x requires taking the address of x , then the function is used and the program is ill-formed if there is no definition for that function.另外,有趣的是,VS 是正确的,因为表达式std::cout << x需要获取x的地址,然后使用function 并且如果没有定义该程序是不正确的即 function。 You can again check that by providing a definition:您可以通过提供定义再次检查:

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

Where I have manually performed the conversion from function to pointer-to-function in the definition of x (1) and the call with the argument f (2) --note that the declaration in 1 and the definition in 3 are the same signature, and that the & in x( &f ) will be performed by the compiler if you don't do it.我手动执行了从functionx (1) 定义中的pointer-to-function的转换以及带有参数f (2) 的调用——注意 1 中的声明和 3的定义是相同的签名,并且如果您不这样做,编译器将执行x( &f )中的&

Just add more parens:只需添加更多括号:

int main()

    {

        int x((int()));

        int y = int();

        cout << x << "  " << y <<  endl;
    }

Now x is an int, not a function.现在 x 是一个 int,而不是 function。

As others have said, x is a function declaration.正如其他人所说, 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. 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++, on the other hand, is complaining that the declared function x is never defined, and thus it can't complete the link.另一方面,Visual C++ 抱怨声明的 function x从未定义,因此无法完成链接。 I suspect g++ in this case is smart enough to see that the function is never called, and thus doesn't worry about the link.我怀疑 g++ 在这种情况下足够聪明,可以看到 function 从未被调用,因此不必担心链接。

You might try adding a dummy definition of the function int x(int(*)()) { return 0xdeadbeef; }您可以尝试添加 function int x(int(*)()) { return 0xdeadbeef; }的虚拟定义。 int x(int(*)()) { return 0xdeadbeef; } to the code and see what MSVC does with it then. int x(int(*)()) { return 0xdeadbeef; }到代码中,然后看看 MSVC 对它做了什么。

C++ interprets the first one as the declaration of a function. C++ 将第一个解释为 function 的声明。

This这个

int x(int());

Is actually a function declaration the input is a function of following signature实际上是一个 function 声明输入是一个 function 的以下签名

int fn(void)

The function pointer passed to std::cout << is converted to a bool(1) as it is a non-NULL pointer.传递给std::cout <<的 function 指针被转换为 bool(1),因为它是一个非 NULL 指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM