std::cout 的意外行为
Unexpected behaviour of std::cout
我最近在玩函数指针,当我发现 std::cout
打印的函数指针的值总是计算为 1。
然而 printf()
并非如此,它打印出预期的结果。
如果有人能解释这种行为背后的原因,那就太好了。
下面是代码示例供参考。
#include<iostream>
using namespace std;
int fun(int a)
{
return 0;
}
int main()
{
cout<<(&fun)<<endl; //always prints 1
printf("%u",&fun); //this prints the expected result
return 0;
}
printf
调用只是未定义的行为。函数指针不是无符号整数,因此为 %u
参数提供它是无效的。 (在 64 位平台上尝试 运行 此代码。您将无法获得正确的函数指针值。)
另一方面,cout
是类型安全的。编译器看到函数指针参数并尝试找到它能找到的最佳打印函数(operator<<
重载)。函数指针本身没有这样的重载,并且指针不提供很多隐式转换。只有一种重载有效,那就是 bool
的重载。所以编译器将非 NULL
函数指针转换为 true
并传递它。然后重载将其打印为 1
,但您可以使用 std::boolalpha
修饰符使其打印为 true
。
您的 cout
将 (&fun)
视为布尔表达式并警告它将始终计算为 true
(即非零)。
尝试将其转换为 void*
,因为应该打印地址,然后检查会发生什么:
#include <iostream>
#include <stdio.h>
using namespace std;
int fun(int a){
return 0;
}
int main(){
cout<<(void*)(&fun)<<endl; //always prints 1
/* Side note: This will print the same as above */
// cout<<(void*)(fun)<<endl; // note the missing &
printf("%p",(void*)&fun); //this prints the expected result
// while(1);
return 0;
}
mu 机器上的输出:
0x401460
0x401460
我最近在玩函数指针,当我发现 std::cout
打印的函数指针的值总是计算为 1。
然而 printf()
并非如此,它打印出预期的结果。
如果有人能解释这种行为背后的原因,那就太好了。
下面是代码示例供参考。
#include<iostream>
using namespace std;
int fun(int a)
{
return 0;
}
int main()
{
cout<<(&fun)<<endl; //always prints 1
printf("%u",&fun); //this prints the expected result
return 0;
}
printf
调用只是未定义的行为。函数指针不是无符号整数,因此为 %u
参数提供它是无效的。 (在 64 位平台上尝试 运行 此代码。您将无法获得正确的函数指针值。)
另一方面,cout
是类型安全的。编译器看到函数指针参数并尝试找到它能找到的最佳打印函数(operator<<
重载)。函数指针本身没有这样的重载,并且指针不提供很多隐式转换。只有一种重载有效,那就是 bool
的重载。所以编译器将非 NULL
函数指针转换为 true
并传递它。然后重载将其打印为 1
,但您可以使用 std::boolalpha
修饰符使其打印为 true
。
您的 cout
将 (&fun)
视为布尔表达式并警告它将始终计算为 true
(即非零)。
尝试将其转换为 void*
,因为应该打印地址,然后检查会发生什么:
#include <iostream>
#include <stdio.h>
using namespace std;
int fun(int a){
return 0;
}
int main(){
cout<<(void*)(&fun)<<endl; //always prints 1
/* Side note: This will print the same as above */
// cout<<(void*)(fun)<<endl; // note the missing &
printf("%p",(void*)&fun); //this prints the expected result
// while(1);
return 0;
}
mu 机器上的输出:
0x401460
0x401460