How do vararg functions find out the number of arguments in machine code?

This is the reason why arguments are pushed on reverse order on the C calling convention, e.g:

If you call:

printf("%s %s", foo, bar);

The stack ends up like:

  ...
+-------------------+
| bar               |
+-------------------+
| foo               |
+-------------------+
| "%s %s"           |
+-------------------+
| return address    |
+-------------------+
| old frame pointer | <- frame pointer
+-------------------+
  ...

Arguments are accesed indirectly using its offset from the frame pointer (the frame pointer can be omitted by smart compilers that know how to calculate things from the stack pointer). The first argument is always at a well-known address in this scheme, the function accesses as many arguments as its first arguments tell it to.

Try the following:

printf("%x %x %x %x %x %x\n");

This will dump part of the stack.


Implicitly, from the format string. Note that stdarg.h doesn't contain any macros to retrieve the total "variable" number of arguments passed. This is also one of the reasons the C calling convention requires the caller to clean the stack, even though this increases code size.


The trick is that you tell them somehow else. For printf you have to supply a format string which even contains type information (which might be incorrect though). The way to supply this information is mainly user-contract and often error-prone.

As for calling conventions: Usually the arguments are pushed onto the stack from left to right and then the backjump address at last. The calling routine clears the stack. So there is no technical need for the called routine to know the number of parameters.

EDIT: In C++0x there is a safe way (even typesafe!) to call variadic functions!