Douglas A. Gwyn said:
However, the specification is based on C function semantics,
and the prototype with the ,...) notation is even part of the
spec, so we know what the linkage interface has to be like.
The "linkage interface"? What is that, in standardese? What exactly does
the standard says about it? How would it be affected if <stdarg.h> were
removed from the standard? Is it really something that the standard
requires to exist, or is it merely a mechanism that compilers commonly use
to implement the required semantics?
Neither the specification of printf() nor the description of function
semantics has references to a "linkage interface". The standard defines
semantics of printf() in terms of the promoted type of the argument. It
says, for instance, that the %u format requires an argument with type
unsigned int, and that if the argument doesn't have the "correct" type, the
behaviour is undefined. There's no hint anywhere that there might actually
be two different correct types for the %u format. There's no hint anywhere
that it's the description of va_arg() that defines what the set of "correct"
types is. There's no hint anywhere that removing <stdarg.h> from the
language could possibly affect the set of "correct" argument types for %u.
Or are all those hints actually there, and I just managed to miss them?
That doesn't seem relevant. Obviously any specific function
has some restriction on its arguments, based on the definition
for the function.
It was just an illustration of the simple fact that what the restrictions on
the arguments is depends on how the semantics of the function are defined.
If the function doesn't use va_arg() or anything else to get the values,
there's no restriction whatsoever. If the function uses
va_arg(ap,unsigned), the restriction is as described for va_arg(): the
argument must be an unsigned int or a non-negative signed int, or else the
behaviour is undefined. If the function is printf() and the format
specifier is %u, the restriction is as described for printf(): the argument
should be an unsigned int and if it doesn't have the correct type, the
behaviour is undefined.
In the case of printf the arguments have to
match up well enough with the format so that the proper values
can be fetched for formatting.
Yes, but how well is well enough? The standard doesn't say that they're
fetched via va_arg() (or "as if" via va_arg()), only that they must have
"the correct type" (notice the singular -- it doesn't say "one of the
correct types"), and names one type for each format specifier. It doesn't
say anything like "a type that has the same representation and alignment
requirements as the specified type", either.
What is "correct" has to be determined in other ways.
Other than by looking it up in the description of printf()?