1

I am reading Linux kernel recently. I find that in many cases they use the struct "typedef xxx f(xxx)", but I cannot understand how it works. (something like function pointer?)

Here is my test code.

#include<stdio.h>
typedef int Myfunc(int);
typedef int (*point_to_myfunc)(int);
static Myfunc example;
static int example(int a){
    printf("example a=%d\n", a);
    return 1;
}
static void example2(Myfunc* f){
    printf("example2\n");
    f(2);
}
static void example3(int (*)(int));
static void example3(int (*point_to_Myfunc)(int)){
    printf("example3\n");
    point_to_Myfunc(3);
}
int main(){
    point_to_myfunc f=&example;
    example2(f);
    example3(f);
    return 0;
}

Can anyone provide a brief explanation for me? Thx~

Mat
  • 202,337
  • 40
  • 393
  • 406
zhoutall
  • 123
  • 1
  • 2
  • 8
  • Is `typedef int Myfunc(int);` even legal? – Shoe Mar 22 '13 at 05:46
  • 2
    @Jueecy Why wouldn't it be? It has a very obvious meaning, so why would the Standard not allow it? if you want to know whether a typedef is legal, just remove "typedef" and see if it's a legal declaration. `int MyFunc(int);` ... yup. – Jim Balter Mar 22 '13 at 05:56

4 Answers4

3
#include <stdio.h>
typedef int Myfunc(int);

Myfunc is the name of a type; it is a function taking an int argument and returning an int.

typedef int (*point_to_myfunc)(int);

point_to_myfunc is a pointer to a function taking an int argument and returning an int. You could also have: typedef Myfunc *ptr_to_myfunc; if you wished (another name for the same type).

static Myfunc example;

This says 'there exists a function called example of type Myfunc'.

static int example(int a)
{
    printf("example a=%d\n", a);
    return 1;
}

This is a possible implementation of example. You can't use a typedef name to like Myfunc in the definition of a function of that type.

static void example2(Myfunc *f)
{
    printf("example2\n");
    f(2);
}

This is a function that takes a pointer to a Myfunc. The line f(2); invokes the function pointed at with the argument 2 and ignores the returned value.

static void example3(int (*)(int));

This declares example3 as a function taking a pointer to a function that takes an int argument and returns an int result. It could have been written as static void example3(point_to_myfunc); or static void example3(ptr_to_myfunc); or static void example3(Myfunc *);.

static void example3(int (*point_to_Myfunc)(int))
{
    printf("example3\n");
    point_to_Myfunc(3);
}

This is an implementation of example3.

int main(void)
{
    point_to_myfunc f = &example;
    example2(f);
    example3(f);
    return 0;
}

This program has a variable f that's a pointer to a function. Interestingly, you could have:

    point_to_myfunc f2 = example;
    point_to_myfunc f3 = *example;

Etc. And they all mean the same thing.

You could also invoke them using:

    (*f2)(101);
    (**f3)(103);

The standard notation for the initialization would use neither the & nor the *. If you're an old school C programmer, you may well invoke the function pointer using the (*f2)(101) notation; before the C89 standard, that was the only way to invoke function pointers. Modern style tends to be f2(101); instead.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1
typedef int Myfunc(int);

This means that Myfunc is the type of a function which takes an int parameter and returns an int.

This line:

static Myfunc example;

is the same as saying

static int example(int);

which forward-declares the example function.

One use for this would be to make it clearer that a particular set of functions are used for a particular purpose.

typedef char CharacterConverter(char);

extern CharacterConverter make_upper_case;
extern CharacterConverter make_lower_case;

extern void process_string(char *s,CharacterConverter *f);
    // easier to see that make_upper_case and make_lower_case are valid arguments.
Jim Balter
  • 16,163
  • 3
  • 43
  • 66
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
1

Vaughn Cato is correct, In addition,

typedef int (*point_to_myfunc)(int);

defines a function pointer, it means point_to_myfunc is a type,we can use it like this:

point_to_myfunc f=&example;

now f is just like example(), we could f() to call method example

TerryZJ
  • 23
  • 5
0

typedef is useful when define a type.

For example: char *a, b; defined a pointer "a", and a char b. char *a, *b defined two char pointers. If use typedef, it will be clear:

typedef char* PCHAR;
PCHAR a,b;

Now, both a and b is a char pointer.

typedef int Myfunc(int);
typedef int (*point_to_myfunc)(int);

the two lines defined a pair, a function format and a type of pointer which can point to the function, so it will be clear and more obvious when using them.

Bing
  • 76
  • 4