繁体   English   中英

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

[英]Why do function pointers all have the same value?

例如:

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

}

有谁知道这背后的原因? 起初我以为这是因为函数不存在于内存中,因为我从不调用它们,因此它们永远不会被添加到堆栈中。 但即使是指向main函数的指针的值也会输出1。

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

这由C ++11§4.10/ 2中的省略指定:

类型为“指向cv T的指针”的prvalue, 其中T是对象类型,可以转换为类型为“指向cv void的指针”的prvalue。 将“指向cv T的指针”转换为“指向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: %p\nfunc2: %p\n", 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;

暂无
暂无

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

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