Re: printf doubt



Keith Thompson wrote:
Joe Wright <joewwright@xxxxxxxxxxx> writes:
Ben Pfaff wrote:
Barry Schwarz <schwarzb@xxxxxxxxx> writes:

On Tue, 11 Jul 2006 10:09:17 -0700, Ben Pfaff <blp@xxxxxxxxxxxxxxx>
wrote:

Barry Schwarz <schwarzb@xxxxxxxxx> writes:

Does not the presence of a superfluous argument lead to undefined
behavior?
No. From C99 7.19.6.1 "The fprintf function":

If the format is exhausted while arguments remain, the
excess arguments are evaluated (as always) but are otherwise
ignored.
I wonder how systems which push return addresses and arguments on the
same stack, like the old 6502, manage this.
What systems use separate stacks for return addresses and
arguments? I am not aware of any in the modern world, so it
would be educational to hear about them. Such a system might be
more resistant to "stack smashing" buffer overflow attacks, for
one thing.

Obviously, fprintf will not pop the superfluous arguments off
the stack since it doesn't even know about them.
A common convention is for the callee to pop off the return
address and leave the arguments on the stack. The caller then
pops the arguments.
Missing the point maybe. There are some number of arguments to printf,
one of them being the format string. Let's assume a format string and
four other expressions. That's five arguments. If the format string
describes what to do with only two expressions, so be it. Only two
will be treated. But five arguments were pushed and five will be
popped.

Which means that a calling convention where the callee needs to know
how many arguments were passed won't work for printf() or other
variadic functions (unless there's an extra implicit argument that
provides that information).

A C compiler *could* use such a convention for non-variadic functions,
but I think most compilers use the same convention for both (since
there was no such distinction in early C).

At least one popular compiler does not. In the documentation for Microsoft Visual Studio .NET under the description for __stdcall it says:
The __stdcall calling convention is used to call Win32 API functions.
The callee cleans the stack, so the compiler makes vararg functions
__cdecl. Functions that use this calling convention require a
function prototype.

So if the compiler is set to use __stdcall by default it will use different calling conventions for variadic and non-variadic functions.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
.



Relevant Pages

  • Re: GCC front-end for FORTH?
    ... ends to generate efficient code for Forth would be hard. ... The return stack is particularly easy, because it has to be balanced ... you need not use a calling convention for most ... doing it in a compiler is that the register allocation will be worse ...
    (comp.lang.forth)
  • Re: Kernel Calling Conventions
    ... The C calling convention is touted as being more convenient, ... passing arguments within registers. ... calling convention is to use registers and not the stack. ... over the DJGPP GCC based compiler, is due to the fact that the OW ...
    (comp.lang.asm.x86)
  • Re: Stack
    ... don't have a processor stack at all. ... If you were implementing a compiler on ... x86 at least, almost always require a stack based calling convention, ... In Windows, for example, you'll find that all ...
    (comp.lang.asm.x86)
  • Re: Kernel Calling Conventions
    ... The C calling convention is touted as being more convenient, ... passing arguments within registers. ... stack as opposed to passing them via registers? ... by the C compiler or tell the C compiler to "reoptimize" your assembly code. ...
    (comp.lang.asm.x86)
  • Re: RfD: IEEE-FP
    ... memory, the alignment of stack items in memory shall be the ... of the floating-point stack shall be at least that of the widest ... n-2: double-fp format implemented ... Almost all implementations do conversion between fp formats by ...
    (comp.lang.forth)