Question

From § 8.3.5.11 of ISO/IEC 14882:2011(E):

A typedef of function type may be used to declare a function but shall not be used to define a function

The standard goes on to give this example:

typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv

What motivates this rule? It seems to limit the potential expressive usefulness of function typedefs.

Was it helpful?

Solution

Though this question is about C++, but since C++ inherits typedef and function pointer from C, so an explanation of the same question in C can be used in here. There's a formal explanation for C.

Rationale for International Standard - Programming Languages C §6.9.1 Function definitions

An argument list must be explicitly present in the declarator; it cannot be inherited from a typedef (see §6.7.5.3). That is to say, given the definition:

typedef int p(int q, int r);

the following fragment is invalid:

p funk // weird
{ return q + r ; }

Some current implementations rewrite the type of, for instance, a char parameter as if it were declared int, since the argument is known to be passed as an int in the absence of a prototype. The Standard requires, however, that the received argument be converted as if by assignment upon function entry. Type rewriting is thus no longer permissible.

OTHER TIPS

It's probably mostly historical reasons. typedef was a relatively late addition to C, and was tacked onto the existing language (and caused a few problems for the parsing phase of compilers).

Also, a function definition has to define the names of the parameters, if any. A function type includes the function's return type and parameter types, but not its parameter names. For example, these:

void (int)
void (int x)
void (int y)

are three ways of writing the same function type. If you had:

typedef void func_t(int);

then this hypothetical definition:

func_t some_func { }

wouldn't define a name for its int parameter. I'm not sure how that could have been resolved in a reasonable manner. It would be possible, I suppose, but it was never done.

But the bottom line is probably just that Dennis Ritchie either didn't think it was worth the effort to define how a typedef could be used in a function definition, or he simply didn't think of it.

Let me put a few words. Consider a statement:

typedef void F(int p1, char* p2);

This statement assigns name F to a function signature void (int, char*); This is definition of an alias to the function signature. After that the statement:

F fv;

tells that there is a function fv. It has the signature that was mentioned above and it has its body somewhere. Look at the C/C++ syntax of the function definition:

retType  funcName(params) { body }

There are actually 2 names used retType and funcName. None of them are the same to the name F from the initial typedef. The name F has meaning of both names. If language would allow something like:

F { body }

this will associate body with the function type. But this leads a problem:

The meaning of F would be not clear. Is it an "alias to the function signature" or is it a "name of the entry point into a code"?

Plus the syntax of the last example would be weird to millions of C/C++ programmers.

The rule is as you quoted - typedef of function type shall not be used to define a function. In the 3rd line of the example, you are trying to define a function with function type F. This is not allowed by the standard.


EDIT
As you pointed out, I try to explain more on it.

For the 3rd line, if it were legal, then you could replace F with the typedef definition:
void fv { }(). This is not a legal definition or declaration in C++.

I think the key point is that typedef is just creating an alias for simplification, and you can replace your typedef type like replacement of #define during compilation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top