Re: libc/printf bug



Jan Panteltje wrote:
On a sunny day (Mon, 27 Feb 2006 23:55:20 GMT) it happened Micah Cowan
<micah@xxxxxxxxxx> wrote in <8764n09wph.fsf@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>:

Jan Panteltje <pNaonStpealmtje@xxxxxxxxx> writes:

On a sunny day (27 Feb 2006 12:09:54 -0800) it happened "bill pursell"
<bill.pursell@xxxxxxxxx> wrote in
<1141070994.179527.261050@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>:

The following code exhibits unexpected behavior. Either it's
a bug in libc, or the author (me) is blind as a bat. Am I missing
something here, or is something horribly wrong? It appears
that printf is mangling the address unless the second argument
gets cast. I don't see that the cast should have any effect at all
on the output. Any thoughts?

[tmp]$ cat printf_bug.c


int
main()
{

float a=0;

printf("%p\n", &a);
printf("%x %p\n", a, &a);
printf("%x %p\n", (int)a, &a);
}
[tmp]$ ./a.out
0xfefb6764
0 (nil)
0 0xfefb6764
[tmp]$

How would you print a float in hex?
Actually, floating point types now have a hexadecimal
representation. See if your system/C-implementation has the "a" and
"A" conversion specifiers.

I think print will convert it to integer, and that is 0.
It will not: variadic functions are "dumb" about what you're passing
it. You have to explicitly cast.
I think when the subroutine is called, the variables are on teh stack.
How much the stackpointerneeds to be incremented for each variable
is set by its type (the function will use that).
So if you wite %x the thing will increment stackpointer by some bytes to
get the next variable.
If that increment was wrong (because you handed it a float), then it
will have the next variable as some part of the current one.
I still think Asm here, push this push that, then index stackpointer
to get those vars back.
'variadic' my foot.

Both, though. The original post hadn't included stdio.h, so all
arguments would be pushed on the stack(typically) as ints. With a
prototype for printf, which accepts varadic arguments, the promotion
rules are different, floats become doubles, char/short become ints and similar.
But yeah, %x might result in reading overlapping arguments vs what
was actually pushed, or result in a trap, or the like.

Main thing is though, if you do something producing undefined behavior
according to C, strange things might happen :-)
.



Relevant Pages

  • Re: libc/printf bug
    ... I don't see that the cast should have any effect at all ... How would you print a float in hex? ... So if you wite %x the thing will increment stackpointer by some bytes to ...
    (comp.os.linux.development.apps)
  • Re: RAD vs. performance
    ... I'm happy to say that ints, floats and sets are not all ... then that's assuming the programmer actually needs a float. ... all is not lost in OCaml. ... Because you need whole-program optimisation for a start. ...
    (comp.lang.misc)
  • Re: dynamic vs. static: the age-old debate
    ... a bignum type in OCaml that has the same operations as ints (including ... I suppose there aren't a lot of algorithms for ints other than ... but I've already stated that it's not a standard float. ... what are the differences in the semantics between ...
    (comp.lang.misc)
  • Re: RAD vs. performance
    ... I've never noticed code repetition between int and float types. ... should the elements be ints ... So can dynamic typing, if designed correctly. ... Because you need whole-program optimisation for a start. ...
    (comp.lang.misc)
  • Re: Convert color-image to bw *fast*
    ... Float: 661 ... optimisations. ... The results basically agree with your assesment on floats and doubles are ... suprisingly close to ints. ...
    (microsoft.public.dotnet.framework.drawing)