为什么函数指针都有相同的值

Why do function pointers all have the same value?

本文关键字:函数 指针 为什么      更新时间:2023-10-16

例如:

using namespace std;
#include <iostream>
void funcOne() {
}
void funcTwo( int x ) {
}
int main() {
  void (*ptrOne)() = funcOne;
  cout << ptrOne << endl;      //prints 1
  void (*ptrTwo)( int x ) = funcTwo;
  cout << ptrTwo << endl;      //prints 1
  int (*ptrMain)() = main;
  cout << ptrMain << endl;     //prints 1
}

有人知道这背后的原因吗?起初我认为这是因为函数不存在于内存中,因为我从未调用过它们,因此它们从未被添加到堆栈中。但是,即使是指向主函数的指针值也会打印出1。

函数指针不会隐式转换为void *,这就是operator <<重载的内容。

这一点在C++11§4.10/2:中有所遗漏

类型为"pointer to cv T"的prvalue,其中T是对象类型,可以转换为类型为"指针到cv void"的prvalue。将"指向cvT的指针"转换为"指向cv void的指针"的结果指向T类型对象所在的存储位置的开始,就好像该对象是T类型的最派生对象(1.8)(即,不是基类子对象)。空指针值转换为目标类型的空指针值。

函数类型不是对象类型。

此外,您甚至不能使用static_cast来执行此操作。函数和对象可能生活在完全不同的地址空间中(这被称为哈佛体系结构),具有不同大小的指针。将函数指针转换为void *可以使用reinterpret_cast:它是"有条件支持的"(C++11§5.2.10/8)。这样的void *只能用于打印或转换回原始函数指针类型。

这样使用它,否则它将转换为bool类型。

cout << reinterpret_cast<void*>(ptrOne) << endl;
C++中的运算符重载增加了各种令人讨厌的复杂性。(它也可以让你做很棒的事情——但有时只是让人头疼。)

正如其他答案中所解释的,C++正在对函数指针进行一些自动类型强制。如果你只使用好的C风格printf,你应该会得到你期望的结果:

#include <cstdio>
// ...
printf("func1: %pnfunc2: %pn", funcOne, funcTwo);

试试这个:

void (*ptrOne)() = funcOne;
cout << reinterpret_cast<void*>(ptrOne) << endl;
void (*ptrTwo)( int x ) = funcTwo;
cout << reinterpret_cast<void*>(ptrTwo) << endl;
int (*ptrMain)() = main;
cout << reinterpret_cast<void*>(ptrMain) << endl;

我认为通常情况下,函数重载规则意味着被调用的<<的版本是operator<<(bool),这意味着:

cout << ptrOne << endl;

转换为:

cout << (ptrOne != NULL) << endl;

与相同

cout << true << endl;