From §6.2.7.5 (page 66):
EXAMPLE Given the following two file scope declarations:
int f(int (*)(), double (*)[3]); int f(int (*)(char
I'm probably not the right person to answer this, but for what it is worth, here is the C99 rationale, which may be helpful:
6.2.7 Compatible type and composite type
The concepts of compatible type and composite type were introduced to allow C89 to discuss those situations in which type declarations need not be identical. These terms are especially useful in explaining the relationship between an incomplete type and a completed type. With the addition of variable length arrays (§6.7.5.2) in C99, array type compatibility was extended so that variable length arrays are compatible with both an array of known constant size and an array with an incomplete type.
Structure, union, or enumeration type declarations in two different translation units do not formally declare the same type, even if the text of these declarations come from the same header file, since the translation units are themselves disjoint. The Standard thus specifies additional compatibility rules for such types so that two such declarations are compatible if they are sufficiently similar.
QUIET CHANGE IN C99
Structures or union type declarations in different translation units now must have identical tags to be compatible.