Function pointers and address of a function

mmirzadeh picture mmirzadeh · Mar 4, 2012 · Viewed 62.1k times · Source

So I figured when making function pointers, you do not need the operator & to get the address of the initial function:

#include <stdio.h>

double foo (double x){
    return x*x;
}

int main () {

    double (*fun1)(double) = &foo;
    double (*fun2)(double) =  foo;

    printf("%f\n",fun1(10));
    printf("%f\n",fun2(10));

    printf("fun1 = %p \t &foo = %p\n",fun1, &foo);
    printf("fun2 = %p \t  foo = %p\n",fun2,  foo);       

    int a[10];

    printf("  a = %p \n &a = %p  \n",a,&a);

    return 0;
}

output:

>./a.out 
100.000000
100.000000
fun1 = 0x4004f4      &foo = 0x4004f4
fun2 = 0x4004f4       foo = 0x4004f4
  a = 0x7fff26804470 
 &a = 0x7fff26804470 

Then I realized this is also true for arrays, meaning that if you have int a[10] both a and &a point to the same location. Why is that with arrays and functions? Is the address saved in a memory location that has the same address as the value(address) being saved in it?

Answer

James McNellis picture James McNellis · Mar 4, 2012

Given int a[10], both a and &a yield the same address, yes, but their types are different.

a is of type int[10]. When it is implicitly converted to a pointer type, the pointer is of type int* and points to the initial element of the array. &a is of type int (*)[10] (that is, a pointer to an array of ten integers). Because there can be no padding in an array, they both yield pointers with the same value, but the pointers have different types.

Functions are similar to arrays, but not entirely the same. Your function foo is of type double(double). Whenever foo is used in an expression and is not the operand of the unary & operator, it is implicitly converted to a pointer to itself, which is of type double(*)(double).

So, for all practical purposes, the name of a function and a pointer to the same function are interchangeable. There are some subtleties, all of which I discuss in an answer to "Why do all these crazy function pointer definitions all work? What is really going on?" (That question was asked about C++, but the rules for nonmember functions in C++ are the same as for functions in C.)