Re: calling convention stdcalll and cdecl call

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



"Alf P. Steinbach" <alfps@xxxxxxxx> wrote
* Liviu:
"Alf P. Steinbach" <alfps@xxxxxxxx> wrote
* Igor Tandetnik:
Alf P. Steinbach <alfps@xxxxxxxx> wrote:
* Igor Tandetnik:
printf("%d", 1, 2);
For what it's worth the above example (1) has undefined behavior

Nope, behavior is both defined and expected (prints 1, excess
arguments
are evaluated but ignored).

In C99. Thanks, I didn't know. Do you have C89 standard?

Don't have it handy, but if google's
http://rm-f.net/~orange/devel/specifications/c89-draft.html#4.9.6.1
is to be trusted, then it's the same:

| If there are insufficient arguments for the format, the behavior is
| undefined. If the format is exhausted while arguments remain, the
| excess arguments are evaluated (as always) but are otherwise ignored.

You might be thinking at "printf("%d");" but even in that case the
"undefinededness" is particular to printf, and has nothing to do with
calling conventions for variadic functions in general.

It had to do with a minor point that Igor may or may not have been
trying to make, who knows since evidently he doesn't mean what he
writes.

I'll go on a limb here ;-) but I trust Igor meant exactly what he wrote:

| With stdcall, the function is responsible for removing its parameters
| from the stack. To do this, it must know how many parameters there
| are, and thus cannot take variable number of parameters.

But just to address what you say, although unrelated to original
context: I'm sorry, but that's incorrect, i.e. contrary to your claim
the behavior of printf has to do with calling conventions for variadic
functions in general.

C99 printf directly supports a functionally limited and generally
inefficient calling convention (C-style) and for printf, makes the
case that that convention doesn't handle, undefined behavior.

Sorry, but I don't follow. The only undefined behavior mentioned there
is when the caller passes _fewer_ arguments than expected from the
format string, and that's because of printf internals. On the other
hand, the standard explicitly states that excess parameters are
ignored, so it's painfully obvious that printf couldn't possibly clear
the stack after itself based on what the format string says.

Imagine for a moment that you'd be writing the __stdcall printf(const
char *, ...) code. At the point your code would be entered, everything
would look _exactly_ the same when the function is called in either of
these ways:

printf("%d", 1);
printf("%d", 1, 2);

How would you code your printf so that it pops the right number of bytes
off the stack in each case?

I replied originally to Igor by posting complete C++ plus assembly
language code for an example of __stdcall variadic arguments.

No. You just provided several overloads of the 'knurre' function which
happened to internally share some assembly code.

If the point of the exercise was to show that passing an additional
"number of params" into a function can allow it to pop the stack itself,
then yes of course it's both possible and trivial. But it's not
__stdcall, since there is no presumption in __stdcall that such a
"number of params" argument must exist.

And, if you proposed a new calling convention which does that, it would
be highly fragile, and something like

knurre(1, 101, 102, 103);

would not only confuse the callee, but also corrupt the entire stack.

Showing that his claim that it was impossible, was simply incorrect.

I requoted his claim above. What part exactly do you find incorrect?

Cheers,
Liviu










.



Relevant Pages

  • Re: User defined stack for threads in Linux 2.6.11 + glibc 2.3.5
    ... If it crashes, what does its stack ... Again, in particular, neither printf, sleep, nor pthread_exit are on the list. ... The redundancy, like your multiple consecutive sleeps, doesn't hurt anything, but the redundancy does redundantly make reading the code more redundant than it really redundantly needs to be. ...
    (comp.programming.threads)
  • Re: about argument pushing order
    ... I really don't think anyone defined an argument passing ... were passed (extra arguments to printf are required to be silently ... C compilers have maintained the same calling conventions use by ... Of course the C standard says nothing about calling conventions. ...
    (comp.lang.c)
  • Re: calling convention stdcalll and cdecl call
    ... "undefinededness" is particular to printf, and has nothing to do with ... But just to address what you say, although unrelated to original context: I'm sorry, but that's incorrect, i.e. contrary to your claim the behavior of printf has to do with calling conventions for variadic functions in general. ...
    (microsoft.public.vc.language)
  • Re: new panic in cpu_reset() with WITNESS
    ... stack: 0xffffff802cda3000 - 0xffffff802cda7000 ... kvprintf() at 0xffffffff80536b1b = kvprintf+0x9b ... vprintf() at 0xffffffff80538225 = vprintf+0x85 ... printf() at 0xffffffff805382f7 = printf+0x67 ...
    (freebsd-current)
  • Re: calling printf from gas for floating point display
    ... but I'm not able to figure out how to get printf to printout floats or doubles. ... the stack pointer, and fstpfrom the FPU stack. ... subl $8, %esp fstpq 0pushl $format_string call printf addl $12, %esp ...
    (alt.lang.asm)