Note that if you put the functions in the same file where they are called (file 2, here), the behavior
changes. The compiler will detect the mismatch of olddef() because it now sees the prototype and
K&R definition together. If you place the definition of newdef() before it is called, the compiler will
silently do the right thing because the definition acts as a prototype, providing consistency. If you
place the definition after the call, the compiler should complain about the mismatch. Since C++
requires prototypes, you may be tempted to add them willy-nilly if using a C++ compiler to brute-
force some antique K&R C code.
Programming Challenge
How to Fake Out Prototypes
Try a few examples to clarify the issues here. Create the following function in a file of its
own:
void banana_peel(char a, short b, float c) {
printf("char = %c, short =%d, float = %f \n",
a,b,c);
}
In a separate file, create a main program that calls banana_peel().
- Try calling it with and without a prototype, and with a prototype that doesn't
match the definition. - In each case, predict what will happen before trying it. Check your prediction
by writing a union that allows you to store a value of one type, and retrieve
another of a different size. - Does changing the order of the parameters (in the declaration and the
definition) affect how the values are perceived in the called function? Account
for this. How many of the error cases does your compiler catch?
Earlier we mentioned that prototypes allow the compiler to check use against declaration. Even if you
don't mix'n'match old style with new style, the convention is not foolproof, as there is no guarantee
that a prototype actually matches the corresponding definition. In practice we guard against this by
putting the prototype into a header file and including the header in the function declaration file. The
compiler sees them both at once and will detect a mismatch. Woe betide the programmer who doesn't
do this!
Handy Heuristic