Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are these two styles of C function pointer definition different?

I have caught myself accidentally using two different styles of C function pointer definitions in different places and have decided to write a minimal program to test these differences.

The two styles in question are:

int (comp (int))

and

int (*comp)(int)

I wrote a minimal program that uses both of these styles for the same function pointer, one for the declaration of a function and one for the definition of the same function, to see what the compiler would have to say about it.

Declaration:

int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));

Definition:

int a_or_b (int (a_fn()), int (*b_fn)(), int (comp(int)))
{
    int out = a_fn ();
    if (comp (out))
        out = b_fn ();
    return out;
}

As you can (hopefully) see, for the first parameter in the declaration I used the style int (*a_fn)(), while in the definition of the function, I used the style int (a_fn ()). I do something similar with the next two arguments.

I speculated that these might be incompatible types, that these styles might be the difference between a pass-by-reference and pass-by-value assignment of the variable, but when I compiled this program the compiler silently and happily compiled it. No errors, no warnings, nothing.

As I've seen very many tutorials advocating for the second style, while I personally prefer the first style for aesthetic purposes, I am interested in what the difference is between these two styles and which is recommended.

Full code example:

#include <stdio.h>

int a ();
int b ();
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));

int a ()
{
    return 1;
}

int b ()
{
    return 2;
}

int comparison (int param)
{
    return param;
}

int a_or_b (int (a_fn()), int (*b_fn)(), int (comp(int)))
{
    int out = a_fn ();
    if (comp (out))
        out = b_fn ();
    return out;
}

int main (int argc, char **argv)
{
    printf ("%i\n", a_or_b (a, b, comparison));
    return 0;
}
like image 334
Marcus Harrison Avatar asked Mar 10 '16 17:03

Marcus Harrison


People also ask

What is difference between function and function pointer in C?

Function Pointers are pointers(like variable pointers) which point to the address of a function. They actually calling the underlying function when you dereference them like a function call does. The main advantage of a function pointer is that you can pass it to another function as a parameter for example ...

What is function pointer with Example Explain How do you declare and define function pointer?

CServer Side ProgrammingProgramming. Function Pointers point to code like normal pointers. In Functions Pointers, function's name can be used to get function's address. A function can also be passed as an arguments and can be returned from a function.

What is the use of function pointer in C?

Function pointers in C can be used to create function calls to which they point. This allows programmers to pass them to functions as arguments. Such functions passed as an argument to other functions are also called callback functions.

What do you mean by function pointer?

A function pointer, also called a subroutine pointer or procedure pointer, is a pointer that points to a function. As opposed to referencing a data value, a function pointer points to executable code within memory.


Video Answer


2 Answers

In a function parameter list, functions get converted to function pointers. The C11 standard, ISO/IEC 9899:2011, §6.7.6.3 Function declarators (including prototypes) says:

¶8 A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type"…

So, as written, the parameters are all treated as 'pointer to function'. It is best to be self-consistent, though.

Note that a function cannot return a function:

¶1 A function declarator shall not specify a return type that is a function type or an array type.

Outside a function declarator (the argument list of a function definition or function declaration), the notations are different:

int (*a_fn)();
int (b_fn());

The first of these declares (defines) a variable called a_fn — a pointer to a function returning int with an unspecified (but not variadic) argument list.

The second of these declares the existence of a function called b_fn that returns an int with an unspecified (but not variadic) argument list (and has a superfluous set of parentheses; it could be written int b_fn(); and it means the same thing).

like image 150
Jonathan Leffler Avatar answered Nov 11 '22 20:11

Jonathan Leffler


Both int (comp (int)) and int (*comp)(int) are equivalent when used as a function parameters. Function designators are converted to pointers to the function itself.

C11-§6.3.2.1:

A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator,65) 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".

like image 29
haccks Avatar answered Nov 11 '22 21:11

haccks