3

If I typedef like this:

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

as defined here

What is this technique called?

If I typedef this way, which means I create a type read_proc_t; later, I create my own version of read-proc-t, which is my_read_proc and I have a struct like this:

struct test {
    read_proc_t read_proc;
} 

struct test t;

I can do something like this:

t.read_proc_t = my_read_proc;

Is this correct? Normally, if I typedef read_proc_t as a function pointer:

typedef int (*read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

I would have to assign my_read_proc function address to the function pointer, like this:

(*t.read_proc_t) = &my_read_proc;

In which circumstance do I choose one?

4 Answers 4

4

The difference is that in the first case the type read_proc_t does not get an implicit pointer semantic, while in the second case it becomes a pointer type.

The difference between the two is that the variables of the first type cannot be created in most contexts. For example, it is illegal to define the struct like this:

struct test {
    // This causes an error in C99:
    // field ‘read_proc’ declared as a function
    read_proc_t read_proc;
};

You need an asterisk to make it valid:

struct test {
    read_proc_t *read_proc;
};

However, read_proc_t can be used to declare function parameters:

void read_something(read_proc_t rd_proc) {
    rd_proc(...); // Invoke the function
}

There is a certain degree of interchangeability between read_proc_t and read_proc_t*: for example, you can call the above function like this:

read_proc_t *rd = my_read_01;
read_something(rd); // <<== read_proc_t* is passed to read_proc_t

In general, you should prefer the first declaration to keep the function pointer semantic explicit, because it is better for readability. If you use the second declaration (with an asterisk) you should name the type in a way that tells the reader that it is a pointer, for example, like this:

typedef int (*read_proc_ptr_t)(char *page, char **start, off_t off,
                      int count, int *eof, void *data);
Sign up to request clarification or add additional context in comments.

Comments

3

It has to be a pointer. So if you typedef it like this:

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

You use it like this

read_proc_t *read_proc = my_read_proc;

And if you typedef it like this:

typedef int (*read_proc_t)(char *page, char **start, off_t off,
                           int count, int *eof, void *data);

You use it like this

read_proc_t read_proc = my_read_proc;

Comments

3
typedef int (read_proc_t)(char *page, char **start, off_t off,
                      int count, int *eof, void *data);

This will define read_proc_t as a function type, you could define a pointer to it, such as read_proc_t *read_proc, but you cannot define a variable of this type. You struct test would not work.

Comments

3

In all absolutely all cases you should prefer to use

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

and not

typedef int (*read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

because the second case hides that the type is a pointer, and this is bad. The first one defines a type that is a function. You cannot have variables of type function in C, but function pointers are fine. So your code should be:

struct test {
    read_proc_t *read_proc;
}

e.g. read_proc is a pointer to a function of type read_proc_t. Notice here that the code clearly expresses what is doing on. With the seconds approach you get read_proc_t read_proc which totally hides the pointer aspect.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.