Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function pointers, arrays and lvalues in C

Tags:

arrays

c

pointers

Let's suppose that we have the following functions (in C):

int sum(int a, int b){  
   return a+b;
}
int diff(int a, int b){
    return a-b;
}

So we know that we can declare an array of funtion pointers in the following way:

int (*test[2]) (int a, int b);
test[0] = sum;
test[1] = diff;

But the following is also valid (but we use heap allocation):

int (**test) (int a, int b) = malloc( 2*sizeof(*test));
test[0] = sum;
test[1] = diff;

So far so good. Now let remember that to declare a (dynamically allocated) array of two integers we can do:

 int* test  = malloc( 2*sizeof(int));

So why we cannot declare an array of function pointers as

int (*test) (int a, int b) = malloc( 2*sizeof(*test)); ?

Is the reason that as test is the same as *test and **test (and so on), malloc( 2*sizeof(*test)) is returning a pointer to a function pointer and therefore it cannot be assigned to (*test) ?

If this supposition is correct, can you explain in detail why we get the compilation error

error: lvalue required as left operand of assignment

when we try to do

int (*test) (int a, int b) = malloc( 2*sizeof(*test));
test=diff; //<--- This is ok.
test+1 = sum; //<--- This is what gives the error!

Disclaimer: I suppose that this is a basic question and the supposition is correct, but I would like a better explanation to have this kind of thing clear one and for all.


Edit:

Notice that this is equivalent to

int (*test) (int a, int b) = malloc( 2*sizeof(*test));
*test=*diff; //<--- This is ok.
*(test+1) = *sum; //<--- This is what gives the error!

as this is somewhat more similar to the case:

int *test = malloc(2*sizeof(*test));
*test = 0;
*(test+1) = 1;
like image 904
Dargor Avatar asked Nov 17 '15 16:11

Dargor


People also ask

What is array of function pointers in C?

Array of Function PointersWe declare and define four functions which take two integer arguments and return an integer value. These functions add, subtract, multiply and divide the two arguments regarding which function is being called by the user.

What are the function of pointers?

A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions and to pass functions as arguments to other functions. You cannot perform pointer arithmetic on pointers to functions.

Is array of function pointer possible in C?

In C, we can use function pointers to avoid code redundancy. For example a simple qsort() function can be used to sort arrays in ascending order or descending or by any other order in case of array of structures. Not only this, with function pointers and void pointers, it is possible to use qsort for any data type.

Are arrays and pointers interchangeable in C?

A common misconception is that an array and a pointer are completely interchangeable. An array name is not a pointer. Although an array name can be treated as a pointer at times, and array notation can be used with pointers, they are distinct and cannot always be used in place of each other.


1 Answers

So why we cannot declare an array of function pointers as

int (*test) (int a, int b) = malloc( 2*sizeof(*test));

Because test does not point to a function pointer; it is a function pointer. Thus it cannot point to the first element of an array of function pointers.

If you want an array of function pointers use the previous form:

int (**test) (int a, int b) = malloc( 2*sizeof(*test));

Here, *test has function pointer type and thus test can (and does) point to the first element of an array of function pointers. Further:

error: lvalue required as left operand of assignment

when we try to do

 int (*test) (int a, int b) = malloc( 2*sizeof(*test));
 test=diff; //<--- This is ok.
 test+1 = sum; //<--- This is what gives the error!

No matter what type test has, test+1=anything is always invalid C. test+1 can never be an lvalue. I don't see why you would expect this to work.

GCC is also papering over another bug in your program, sizeof(*test). Since *test has function type, sizeof(*test) is invalid, but GCC silently assigns it the value 1. This results in allocating too little memory for a function pointer, but it doesn't matter anyway because in the following line you throw away the memory you got from malloc and assign something else to test.

like image 175
R.. GitHub STOP HELPING ICE Avatar answered Sep 19 '22 04:09

R.. GitHub STOP HELPING ICE