7

I wrote some code to know how function pointer works. I run the following C++ code on some IDEs, the results are the same.

#include "stdafx.h"

int *function(){
    static int a=1;
    return &a;
}
typedef struct{
    int *(*pt_1)();
    int *(*pt_2)();
}x_t;
int _tmain(int argc, _TCHAR* argv[])
{
    x_t s;
    s.pt_1 = function;
    s.pt_2 = &function;

    printf("%x\n",s.pt_1);    //Result: 0x013011a9
    printf("%x\n",*s.pt_1);   //Result: 0x013011a9 
    printf("%x\n",**s.pt_1);  //Result: 0x013011a9
    printf("%x\n",s.pt_1());  //Result: 0x01307000
    printf("%x\n",*s.pt_1()); //Result: 1

    printf("%x\n",s.pt_2);    //Result: 0x013011a9
    printf("%x\n",*s.pt_2);   //Result: 0x013011a9
    printf("%x\n",**s.pt_2);  //Result: 0x013011a9
    printf("%x\n",s.pt_2());  //Result: 0x01307000
    printf("%x\n",*s.pt_2()); //Result: 1

    return 0;
}

My questions:

    1. Why s.pt_1 == s.pt_2 == *s.pt_1 = **s.pt_1 ?
    1. Where address does the s.pt_1() point to ? Where does it locate on memory?
Mat
  • 202,337
  • 40
  • 393
  • 406
Ngo Thanh Nhan
  • 503
  • 2
  • 5
  • 17
  • 3
    1, see [this](http://stackoverflow.com/questions/2795575/how-does-dereferencing-of-a-function-pointer-happen). 2. `operator()` calls the function, so you're working with its returned pointer. – LogicStuff Jan 24 '16 at 09:33
  • 1
    printing function pointers by `%x` invokes undefined behavior, as addresses might not fit an `int`. Use `printf("%p\n",(void*)s.pt_1);` – phuclv Jan 24 '16 at 10:11
  • I found the answer for the second question here [Where in memory are return values stored in memory?](http://stackoverflow.com/questions/5472008/where-in-memory-are-return-values-stored-in-memory) – Ngo Thanh Nhan Jan 25 '16 at 06:20

2 Answers2

4

Similar to using the name of an array, using the name of a function will make it decay into a pointer at the slightest provocation.

s.pt_1 = function;    

Here function decays into a pointer to the function.

s.pt_2 = &function;

Here you actually take the address of the function, which results in the same pointer as in the first case.

printf("%x\n",s.pt_1);    //Result: 0x013011a9
printf("%x\n",*s.pt_1);   //Result: 0x013011a9 
printf("%x\n",**s.pt_1);  //Result: 0x013011a9

On the first line pt_1 is a pointer to a function, and the address stored in the pointer is displayed.

On the second line, you dereference the pointer and gets access to the function itself. Which the decays into a pointer when passed to a function.

On the third line, you dereference the pointer to get the function, which then decays to a pointer when you use it with another *. The second star results in a value that again decays into a pointer when passed to a function. Etc.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

The problem is that you cannot basically do anything with a "function object"... C++ only manages "pointers to function".

Therefore a function will implicitly decay into a pointer to the function for any use... it doesn't matter how many * you put in front of it.

Something similar happens with arrays, where they implicitly decay into a pointer to the first element, with the difference that you can do some operation on arrays (e.g. sizeof) while even this is forbidden with functions.

Given than in C++ there's no (portable) way to create new functions at runtime the limitation of not being able to manipulate function objects is not really important. You can only deal with pointers to existing functions anyway...

6502
  • 112,025
  • 15
  • 165
  • 265