Re: [PATCH] Re: [ipchains] logging tcp/udp port numbers

Mikael Pettersson (mikpe@csd.uu.se)
Thu, 19 Nov 1998 13:09:03 +0100 (MET)


Linus Torvalds writes:
> On Wed, 18 Nov 1998, R Shapiro wrote:
> > Linus Torvalds writes:
> > > it (ie instead of using
> > >
> > > num = va_arg(args, short);
> > >
> > > it might be proper to use
> > >
> > > num = (short) va_args(args, int);
> ...
> Yes, I'm almost positive that the second version is always correct due to
> the C language rules about integer promotions.
>
> However, I also suspect that the first version really _should_ work, and
> that it really is a problem in gcc or the varargs header files that makes
> it not work.
>
> Alternatively, I'd really like to know whether maybe the C standard really
> says that you _have_ to use the second form. It's possible it does.

The second form is the correct one, as it has always been, regardless of
what gcc may or may not accept on some machines.
The Gospel, as interpreted by "ISO/IEC JTC1/SC22/WG14 - C" in the C9X Final
Committe Draft, says this about va_arg on page 235, section 7.15.1.1:

Synopsis
#include <stdarg.h>
type va_arg(va_list ap, type);

Description
..
The parameter \emph{type} shall be a type name specified such that
the type of a pointer to an object that has the specified type can
be obtained simply by postfixing a \texttt{*} to \emph{type}.
If there is no actual next argument, or if \emph{type} is not
compatible with the type of the actual next argument (as promoted
according to the default argument promotions), the behavior is
undefined, ...

As if this wasn't clear enough, the C9X Rationale states explicitly
(page 112, section 7.15.1.1) that:

..
it is important to remember that the type of an argument in a
variable argument list will never be an integer type smaller than
\texttt{int}, not will it ever be \texttt{float}.

It is not difficult to imagine at least two ways in which the first, buggy,
form "va_arg(args, short)" can misbehave: using a "short*" pointer to access
an "int", and incrementing the variable argument list "pointer" as if the
argument was "short" instead of "int".

Maybe gcc's <stdarg.h> contains a DWIM (*) which works on some machines, but
I wouldn't count on it. Just use the correct C code and don't worry, OK?

/Mikael

(*) DWIM = Do What I Mean, the name given to an automatic error correction
assistant in the Interlisp programming environment. I never liked it.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/