Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

correct way to assign function pointer

I'm a little confused about the correct syntax for assigning a function pointer to a variable. If I have a function foo

int foo();

and I am assigning a pointer to foo to variable bar

void * bar;

it does not seem to matter if I use

bar = foo; 
// or 
bar = &foo; 

It seems to me that only one of these should be correct or am I missing something?

like image 269
Richard Johnson Avatar asked Mar 07 '13 20:03

Richard Johnson


2 Answers

foo and &foo values are equivalent in C and have same type.

The & operator here is correct but redundant.

Note that assigning a function pointer to a void * is not valid in C.

void *fp1 = foo;   // invalid
int (*fp2)() = foo;  // valid
int (*fp3)() = &foo; // valid

(These are actually declarations but the constraints of the assignment operator apply.)

like image 128
ouah Avatar answered Nov 05 '22 20:11

ouah


Let me explain a bit more.

foo and &foo values are equivalent in C and have same type.

This is not fully correct as pointed out by the comments to the answer by @ouah. Particularly:

  1. sizeof(foo) is invalid, and sizeof(&foo) is the size of a pointer.
  2. &foo is the pointer to foo, while &(&foo) is invalid.

However, they are actually the same in all the other cases, as is mentioned by the standard of C (reference to, e.g., the draft of C11):

6.3.2.1.4: A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".

The sizeof and unary & operators are the only two exceptions when a function designator is not converted to a pointer.

P.S. You can also find why sizeof(foo) and &(&foo) is invalid:

6.5.3.2.1: The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

6.5.3.4.1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.

like image 36
Colliot Avatar answered Nov 05 '22 22:11

Colliot