简体   繁体   中英

Why do function pointers all have the same value?

For example:

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

}

Does anyone know the reasoning behind this? At first I thought it was because the functions don't exist in memory since I never call on them, and thus they never get added to the stack. But even the value of a pointer to the main function prints out 1.

Function pointers do not implicitly convert to void * , which is what operator << overloads on.

This is specified by omission in C++11 §4.10/2:

A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject). The null pointer value is converted to the null pointer value of the destination type.

Function types are not object types.

Moreover, you can't even do it using static_cast . Functions and objects may live in completely different address spaces (this is called Harvard architecture), with differently-sized pointers. Converting a function pointer to void * can maybe be done with reinterpret_cast : it's "conditionally-supported" (C++11 §5.2.10/8). Such a void * should only be used for printing or conversion back to the original function pointer type.

像这样使用它,或者它将被转换为bool类型。

cout << reinterpret_cast<void*>(ptrOne) << endl;

Operator overloading in C++ adds all sorts of nasty complexities. (It lets you do awesome stuff too—but sometimes it's just a headache.)

As explained in the other answers, C++ is doing some automatic type coercion on your function pointers. If you just use the good ol' C-style printf you should get the results you're expecting:

#include <cstdio>

// ...

printf("func1: %p\nfunc2: %p\n", funcOne, funcTwo);

Try this instead:

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;

I think normally, function overloading rules mean that the version of << being called is operator<<(bool) , which means:

cout << ptrOne << endl;

Gets transformed into:

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

Which is the same as:

cout << true << endl;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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