[LCP]puzzling

Greg Black gjb at gbch.net
Sun Mar 2 11:32:02 UTC 2003


Andrew Weaver wrote (lots snipped):

| On Friday, February 28, 2003 10:08 AM, Greg Black [SMTP:gjb at gbch.net] wrote:
| > Kurian Abraham Kurian Abraham-A18108 wrote:
| > 
| > |   printf("\nAmazing = %ld",(b - a)*(16.66));
| > 
| > They are expected to be different -- the program is wrong.
| > 
| > In the "amazing" line, you tell printf() to expect a long, but
| > you pass it a double.  You get what you asked for.
| 
| My theory is that the calc of the varargs going on inside printf...

I can't tell from this whether you understand this correctly or
not, so here's a slightly longer explanation than my first one.
Bear in mind that this is all *basic* C, and you must be clear
about it (i.e., not needing theories) if you hope to use this
simple and powerful language.

In the printf() call shown above, we see printf() called with
two arguments: a `char *' (the required first argument) and a
`double' (the first and only optional "vararg").  I doubt if
anybody is having trouble with the first arg, so let's look at
the second one.

Here it is again, expressed as types:

    (long - long) * (double)

By definition, such an expression results in a `double'.  This
is never in question and is totally unambiguous.

However, in the first argument, we told printf() to expect a
`long' as the next argument.  So it just interprets (part of)
the actual `double' that was passed in as a `long' and then
displays garbage.

Decent modern compilers such as gcc will provide clear warnings
about this kind of error if warnings are turned on -- but only
for varargs functions that they understand.  So you need to be
on top of what happens here so that you can cope when you make
the same mistakes with other varargs functions.

But everybody needs to quite clear about this -- it's not at all
surprising or difficult to understand, because it's all set out
in the definition of the language.

Greg



More information about the linuxCprogramming mailing list