Syntactically, typedef
is treated as storage class specifier, like extern
or static
. It doesn't actually specify a storage class; it's just defined that way for convenience. So you can replace typedef
by static
and get a declaration with a different meaning, but similar syntax, and defining the same identifier.
You have:
typedef int (*pf) (int, int);
Replacing typedef
by static
gives:
static int (*pf) (int, int);
which declares a function pointer named pf
. The typedef
version of the declaration also declares the identifier pf
, but as a type name, not as a pointer object.
Keep in mind that typedef
doesn't create a new type, merely a new name for an existing type. Rather than declaring pf
as an object, the typedef
declaration makes pf
an alias for the type name int (*)(int, int)
.
Since storage class specifiers are optional, you can also understand a complex typedef
declaration by dropping the word typedef
:
int (*pf) (int, int);
which declares pf
as an object of type int (*) (int, int)
.
You can also use the cdecl
program to explain complex declarations like this. It doesn't understand typedef
(as of version 2.5), but you can just drop the typedef
keyword:
$ cdecl
Type `help' or `?' for help
cdecl> explain typedef int (*pf) (int, int);
syntax error
cdecl> explain int (*pf) (int, int);
declare pf as pointer to function (int, int) returning int
cdecl>
If you don't have the cdecl
program installed on your system, there's an online version at http://cdecl.org/