2

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~

2
  • Is typedef int Myfunc(int); even legal? Commented Mar 22, 2013 at 5: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. Commented Mar 22, 2013 at 5:56

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for your clear explanation. This usage is really powerful.
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

Comments

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.

3 Comments

what would be the practical use of such typedef?
@Koushik: I've added one possible use.
+1. ah nice. there is a typo. its characterConverte(r) not (d).
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.

2 Comments

The OP didn't ask what typedef is or for an example of what it's good for.
You're right, My mistake.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.