Expert C Programming

(Jeff_L) #1

versions of the standard. For the foreseeable future both styles will coexist, because of the volume of
pre-ANSI code. So, if prototypes are "a good thing," should we use them everywhere, and go back and
add prototypes to existing code when we conduct maintenance on it? Emphatically not!


Function prototypes not only change the syntax of the language; they also introduce a subtle (and
arguably undesirable) difference into the semantics. As we know from the previous section, under
K&R, if you passed anything shorter than an int to a function it actually got an int, and floats were
expanded to doubles. The values are automatically trimmed back to the corresponding narrower types
in the body of the called function, if they are declared that way there.


At this point, you might be wondering, why bother expanding them at all, only to shrink them back? It
was originally done to simplify the compiler—everything became a standard size. With just a few
types it especially simplified argument passing, especially in very old K&R C where you couldn't pass
structs as arguments. There were exactly three types: int, double, and pointer. All arguments became a
standard size, and the callee would narrow them if necessary.


In contrast, if you use a function prototype, the default argument promotions do not occur. If you
prototype something as a char, a char actually gets passed. If you use the new-style function
definition (where argument types are given in the parentheses following the function name), then the
compiler generates code on the assumption that the parameters are exactly as declared, without the
default type widening.


Where Prototypes Break Down


There are four cases to consider here:



  1. K&R function declaration, and K&R function definition


call works ok, promoted types are passed


  1. ANSI C declaration (prototype), and ANSI C definition


call works ok, actual types are passed


  1. ANSI C declaration (prototype), and K&R function definition


Failure if you use a narrow type! Call passes actual


types, function expects promoted types.





    1. K&R function declaration, and ANSI C definition




Failure if you use a narrow type! Call passes promoted


types, function expects actual types.

Free download pdf