### Question 11.3

My ANSI compiler complains about a mismatch when it sees

    	extern int func(float);

    	int func(x)
    	float x;
    	{ ...

You have mixed the new-style prototype declaration ```extern int func(float);`'' with the old-style definition ```int func(x) float x;`''. It is usually safe to mix the two styles (see question 11.4), but not in this case.

Old C (and ANSI C, in the absence of prototypes, and in variable-length argument lists; see question 15.2) ``widens'' certain arguments when they are passed to functions. `float`s are promoted to `double`, and characters and short integers are promoted to `int`. (For old-style function definitions, the values are automatically converted back to the corresponding narrower types within the body of the called function, if they are declared that way there.)

This problem can be fixed either by using new-style syntax consistently in the definition:

    	int func(float x) { ... }

or by changing the new-style prototype declaration to match the old-style definition:

    	extern int func(double);

(In this case, it would be clearest to change the old-style definition to use `double` as well, as long as the address of that parameter is not taken.)

It may also be safer to avoid ``narrow'' (`char`, `short int`, and `float`) function arguments and return types altogether.

See also question 1.25.

References: K&R1 Sec. A7.1 p. 186
K&R2 Sec. A7.3.2 p. 202
ANSI Sec. 3.3.2.2, Sec. 3.5.4.3
ISO Sec. 6.3.2.2, Sec. 6.5.4.3
Rationale Sec. 3.3.2.2, Sec. 3.5.4.3
H&S Sec. 9.2 pp. 265-7, Sec. 9.4 pp. 272-3

Read sequentially: prev next up top

This page by Steve Summit // Copyright 1995 // mail feedback