On Wed, Mar 06, 2002 at 08:56:18PM -0800, Yitzchak Scott-Thoennes wrote: > >Apparently, when I did a "man printf", I got the one in FreeBSD's Section 1: > >> The format string is reused as often as necessary to satisfy the > >> arguments. Any extra format specifications are evaluated with zero or > >> the null string. > > Thats funky.
this is section *1* manual, for commands, right? It's possible that printf *program* does that, but that's really weird. (yes, indeed: printf(1) FreeBSD 3.5, Linux 2.2.14, and SunOS 5.8 aka Solaris 8 are documented and work this way.) > POSIX (IEEE 1003.1-2001) says: > If the format is exhausted while arguments remain, the excess > arguments shall be evaluated but are otherwise ignored. > > And C99 (ISO 9899-1999 section 7.19.6.1) says: > If the format is exhausted while arguments remain, the excess > arguments are evaluated (as always) but are otherwise ignored. > > Does it in fact reuse the format on your system? If one remembers how C argument passing convention works on assembly level (and different from Pascal conversion for example), it is that arguments are pushed to stack by caller, last to first, then subroutine is called, and stack popped (possibly delayed or combined with another stack operation down the road.) Therefore, it is impossible for called function to know number of arguments it has passed. (Unless printf() is implemented in the language compiler.) For example, the following program (pardon terse style): #include <stdio.h> #define NARGS 10 int main() { int i; int n[NARGS]; for (i = 0; i < NARGS; i++) { n[i] = i; } printf("%d,\n", n[0], n[1], n[2], n[3]); return 0; } produces the following output: 0, and compiles to the following code, which does not pass 4 as number of non-format arguments to printf at any way: .file "test-printf.c" .version "01.01" gcc2_compiled.: ..section .rodata ..LC0: .ascii "%d,\12\0" ..text .p2align 2 ..globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $40,%esp xorl %eax,%eax .p2align 2,0x90 ..L9: movl %eax,-40(%ebp,%eax,4) incl %eax cmpl $9,%eax jle .L9 pushl -28(%ebp) pushl -32(%ebp) pushl -36(%ebp) pushl -40(%ebp) pushl $.LC0 call printf xorl %eax,%eax leave ret ..Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.7.2.3"