我遇到了以下代码的奇怪行为,同时使用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)
我在哪里已经手动执行的转换从function
到pointer-to-function
的定义中x
(1),并用参数中的呼叫f
(2) -注,在1的声明和3中的定义是相同的签名,并且该&
在x( &f )
将被执行由编译器,如果你不这样做.
归档时间: |
|
查看次数: |
615 次 |
最近记录: |