Mail Archives: djgpp/1996/06/07/02:44:59
Reply to message 8896876 from MAX AT ALCYONE DOT C on 06/05/96 10:33PM
>The second problem was that of using printf in this manner. The compiler has
>no way of knowing that the first parameter to the variable argument list is
>_supposed to be_ a float (it has the %f format specifier), when in actuality
>it is of integral type. This is a Bad Thing.
Actually, the compiler is quite smart about the *printf and *scanf functions -
it examines the format string and compares it to the type of each argument
to make sure you are doing things correctly. Make sure that you compile
with -Wall to get all such warnings.
However, in some cases, like expressions used as arguments, the
compiler treats the expression in the same way it would an assignment
to a variable of the type indicated by the format string, i.e., it promotes
or demotes it to the correct type, and usually doesn't give you a warning
about it. For example, the following expression is perfectly valid in C:
int a, b, c;
float x;
x = a * b + c;
because it is evaluated as an integer expression and promoted to
float before being assigned to x. This is perfectly correct and normal
behavior and if it were to cause a warning, it would drive a lot of
programmers stark raving nuts. :)
Of course, I do agree that implicit casting within printf() calls is bad
programming - it's too easy to make silly mistakes.
BTW, you can use __attribute__ ((format (type, format-arg, arg-to-check) ))
in a function prototype to force a function to be evaluated as if it were
a printf() or scanf() type function. "type" is either "printf" or "scanf",
"format-arg" is the number (starting with 1) of the argument containing
the format string, and "arg-to-check" is the number of the '...' argument.
It's all in the gcc docs, and makes some fascinating reading. I used it
myself to create a set of wrapper functions for some school programs
which output data to both the screen and a printer or disk file
simultaneously.
John
- Raw text -