Are these compatible function types in C?

These two defect reports address your issue:

  • Defect Report #316
  • Defect Report #317

Defect report 316 says (emphasis mine going forward):

The rules for compatibility of function types in 6.7.5.3#15 do not
define when a function type is “specified by a function definition

that contains a (possibly empty) identifier list”, […]

and it has a similar example to the one you give:

void f(a)int a;{}
void (*h)(int, int, int) = f;

and it goes on to say:

I believe the intent of the standard is that a type is specified by a
function definition only for the purposes of checking compatibility of
multiple declarations of the same function
; when as here the name of
the function appears in an expression, its type is determined by its
return type and contains no trace of the parameter types. However,
implementation interpretations vary.

Question 2: Is the above translation unit valid?

and the answer from the committee was:

The Committee believe the answers to Q1 & 2 are yes

This was between C99 and C11 but the committee adds:

We have no intention of fixing the old style rules. However, the
observations made in this document seem to be generally correct.

and as far a I can tell C99 and C11 do not differ greatly in the sections you have quoted in the question. If we further look into defect report 317 we can see that it says:

I believe the intent of C is that old-style function definitions with
empty parentheses do not give the function a type including a
prototype
for the rest of the translation unit. For example:

void f(){} 
void g(){if(0)f(1);}

Question 1: Does such a function definition give the function a type
including a prototype for the rest of the translation unit?

Question 2: Is the above translation unit valid?

and the committees response was:

The answer to question #1 is NO, and to question #2 is YES. There are
no constraint violations, however, if the function call were executed
it would have undefined behavior. See 6.5.2.2;p6.

This seems to hinge on the fact that it is underspecified whether a function definition defines a type or a prototype and therefore means there is no compatibility checking requirements. This was originally the intent with old style function definitions and the committee will not clarify further probably because it is deprecated.

The committee points out that just because the translation unit is valid does not mean there is no undefined behavior.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)