It was thus said that the Great Dave Dunfield once stated:
Hmmm ...
void print_arg(int *aryp,size_t n)
{
printf("%u",*aryp++);
while(--n)
{
printf(",%u",*aryp++);
}
putchar('\n');
}
But has two calls to printf, with different format
strings. More than doubles the static string space.
Plus two complete printf call frames (bigger code)...
one being used only once.
Well ... one could do:
void print_arg(int *aryp,size_t n)
{
static const char text[] = ",%u";
printf(text+1,*aryp++);
while(--n)
{
printf(text,*aryp++);
}
putchar('\n');
}
Which I stuffed through GCC 2.7.2.3 (admittedly not a recent version of
GCC) using the following command line:
% gcc -S -O2 -fomit-frame-pointer t.c
And got the following (cleaned up):
.section rodata
text .text ",%u"
.section code
print_arg push esi
push ebx
mov esi,[esp + 12]
mov ebx,[esp + 16]
push dword ptr [esi]
add esi,4
push offset text + 1
jmps .L11
.L9 push dword ptr [esi]
add esi,4
push offset text
.L11 call printf
add esp,8
dec ebx
jne .L9
push dword $_IO_stdout
push dword 10
call _IO_putc
add esp,8
pop ebx
pop esi
ret
Surprised me! A single call to printf(). Not bad---then again, GCC had
been in development for quite a long time. And the printf() stack frame is
no different from any other C stack frame (in declaration yes, but not in
how it works).
gotos and other such structures are not evil - lack
of understanding of when such constructs are
appropriate (and not appropriate) is the real
problem. "Banning" the constructs just serves to
emphasize that this is not obvious to some people.
Hmmm... we seem to be sailing away from the topics
again!
Oh dear, we are, aren't we?
-spc (And the assembly output has one unconditional GOTO and one
conditional GOTO ... but who's counting?)