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