tags:

views:

140

answers:

3
typedef int (fc_name) (void);

here fc_name is any valid C symbol.

how different is this from a function pointer typedef ?

+6  A: 

The first parentheses are superfluous - it is equivalent to:

typedef int fc_name(void);

I don't think this does anything useful, though I can't get GCC to complain about it on its own.

A pointer to function typedef would read:

typedef int (*fc_name)(void);

This code shows that the typedefs without the asterisk are not function pointers (addressing a now-deleted alternative answer):

static int function(void)
{
    return 0;
}

typedef int   fc_name1 (void);
typedef int  (fc_name2)(void);
typedef int (*fc_name3)(void);

fc_name1 x = function;
fc_name2 y = function;
fc_name3 z = function;

When compiled, 'gcc' says:

gcc -Wextra -Wall -pedantic -c -O x.c
x.c:10:1: error: function ‘x’ is initialized like a variable
x.c:11:1: error: function ‘y’ is initialized like a variable

And this code demonstrates that you can indeed use fc_name *var = funcname; as suggested by jamesdlin:

static int function(void)
{
    return 0;
}

typedef int   fc_name1 (void);
typedef int  (fc_name2)(void);
typedef int (*fc_name3)(void);

fc_name1  x_0 = function;
fc_name1 *x_1 = function;
fc_name2  y_0 = function;    // Damn Bessel functions - and no <math.h>
fc_name2 *y_1 = function;    // Damn Bessel functions - and no <math.h>
fc_name3  z   = function;

Using y0, y1 generates GCC warnings:

x.c:12:11: warning: conflicting types for built-in function ‘y0’
x.c:13:11: warning: built-in function ‘y1’ declared as non-function

And, building on the comment from schot:

static int function(void)
{
    return 0;
}

typedef int   fc_name1 (void);
typedef int  (fc_name2)(void);
typedef int (*fc_name3)(void);

fc_name1  x_0 = function;   // Error
fc_name1 *x_1 = function;   // x_1 is a pointer to function
fc_name1  x_2;              // Declare int x_2(void);
fc_name1 *x_3 = x_2;        // Declare x_3 initialized with x_2

fc_name2  y_0 = function;   // Damn Bessel functions - and no <math.h>
fc_name2 *y_1 = function;   // Damn Bessel functions - and no <math.h>
fc_name1  y_2;              // Declare int y_2(void);
fc_name1 *y_3 = x_2;        // Declare y_3 initialized with y_2

fc_name3  z   = function;

Interesting - the dark corners of C are murky indeed.

Jonathan Leffler
Some people prefer the typedef to be of the function signature pre-pointer-taking. That shifts the "explictness" of taking a pointer to the declaration of each function pointer. It's a matter of style, I think.
detly
You can also use a function `typedef` for a function *declaration* (prototype), but not for a *definition*. But this is not very useful, except for obfuscation.
schot
@schot: Neat, I didn't know it could be used for function declarations. I actually do think that is kind of useful for declaring a set of callback functions; previously I was using a preprocessor macro to simplify that.
jamesdlin
+10  A: 

It's a typedef to a function type. The intent is to use it for function pointers, but in this case the syntax to use it would be:

int bar(void);

fc_name* foo = bar; /* Note the * */
jamesdlin
+1: Ah - so that's how it gets to be useful! I've demonstrated that you're correct - but only once you showed me how. We live, we learn; SO rocks.
Jonathan Leffler
A: 
  1 #include <stdio.h>
  2 
  3 
  4 typedef int (fc_name)(void);
  5 
  6 
  7 
  8 int test_func1 ()
  9 {
 10     printf("\n test_func1 called\n");
 11 
 12     return 0;
 13 }
 14 
 15 int test_func2 (void)
 16 {
 17     printf("\n test_func2 called\n");
 18     return 0;
 19 }
 20 
 21 int handler_func(fc_name *fptr)
 22 {
 23     //Call the actual function
 24     fptr();
 25 }
 26 
 27 int main(void)
 28 {
 29     fc_name  *f1, *f2;
 30 
 31     f1 = test_func1;
 32     f2 = test_func2;
 33 
 34     handler_func(f1);
 35     handler_func(f2);
 36 
 37     printf("\n test complete\n");
 38 
 39     return 0;
 40 }

OUTPUT:-

test_func1 called

test_func2 called

test complete

So the typedef which I questioned about, (Line # 4 here) represents a function type and is not the same as function pointer typedef. This kind of typedef is not much significance. These are used as a style standard or simply to create obfuscation intentionally ;-)

Saran