develooper Front page | perl.fwp | Postings from March 2002

Re: rethinking printf

Thread Previous | Thread Next
From:
Dmitry Kohmanyuk Дмитрий Кохманюк
Date:
March 6, 2002 22:38
Subject:
Re: rethinking printf
Message ID:
20020306223747.G66626@farm.org
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"


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About