public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* The printf format
@ 2013-01-14 14:09 GHui
  2013-01-14 14:55 ` Mihai Donțu
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: GHui @ 2013-01-14 14:09 UTC (permalink / raw)
  To: gcc-help


I code the following code.
--------------------------
#include <stdio.h>
int main(int argc,char **argv)
{
    float f[2]={4.0, 37.4};
    printf("%.2f    %.2f\n",f[0],f[1]);
    printf("%d    %.2f\n",f[0],f[1]);
}

And it output is following.
-------------------------
4.00    37.40
-1    4.00

I confuse that f[1] is 4.00 at the second line.
Any help will be appreciated.

--GHui

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: The printf format
  2013-01-14 14:09 The printf format GHui
@ 2013-01-14 14:55 ` Mihai Donțu
  2013-01-14 15:33 ` Ángel González
  2013-01-14 16:22 ` Jonathan Wakely
  2 siblings, 0 replies; 4+ messages in thread
From: Mihai Donțu @ 2013-01-14 14:55 UTC (permalink / raw)
  To: gcc-help

On Mon, 14 Jan 2013 19:29:19 +0800 GHui wrote:
> I code the following code.
> --------------------------
> #include <stdio.h>
> int main(int argc,char **argv)
> {
>     float f[2]={4.0, 37.4};
>     printf("%.2f    %.2f\n",f[0],f[1]);
>     printf("%d    %.2f\n",f[0],f[1]);
> }
> 
> And it output is following.
> -------------------------
> 4.00    37.40
> -1    4.00
> 
> I confuse that f[1] is 4.00 at the second line.
> Any help will be appreciated.
> 

Off the top of my head: the second printf pulls the argument for "%d"
from the general set of registers, while the one for "%.2f" is taken
from the SSE registers. At least on amd64. For x86 it has something to
do with how the float arguments are placed on stack (unlike int-s). You
can probably get a better image with:

  $ objdump -D -C -l -j .text <binary> | vim -

-- 
Mihai Donțu

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: The printf format
  2013-01-14 14:09 The printf format GHui
  2013-01-14 14:55 ` Mihai Donțu
@ 2013-01-14 15:33 ` Ángel González
  2013-01-14 16:22 ` Jonathan Wakely
  2 siblings, 0 replies; 4+ messages in thread
From: Ángel González @ 2013-01-14 15:33 UTC (permalink / raw)
  To: GHui; +Cc: gcc-help

On 14/01/13 12:29, GHui wrote:
> I code the following code.
> --------------------------
> #include <stdio.h>
> int main(int argc,char **argv)
> {
>     float f[2]={4.0, 37.4};
>     printf("%.2f    %.2f\n",f[0],f[1]);
>     printf("%d    %.2f\n",f[0],f[1]);
> }
>
> And it output is following.
> -------------------------
> 4.00    37.40
> -1    4.00
>
> I confuse that f[1] is 4.00 at the second line.
> Any help will be appreciated.
>
> --GHui
In the second case you are pushing two floats to the stack.
Then printf tries to pop an integer and a float.
You need to take into account that in variable-length arguments,
floats get promoted into double, so even if int and float are of the
same size in your system (something on which you can't rely), printf
is actually poping a double (probably not the size of your int).
When you lie in the arguments you pass, you can get all kind of
garbage. Specially when floats and doubles are, since they are
sometimes passed in special registers (depending on the ABI).
In this case, I think that the 4.0 you are getting is f[0] passed in
a special register, and you would have been shown 37.40 if
adding a second %.2f. But those are internals of the ABI.
Respect the parameter formats and all will be good.


If you want to print f[0] as an integer use:

printf("%d    %.2f\n",(int)f[0],f[1]);


This kind of bug is warned by gcc when using -Wformat (included in -Wall).

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: The printf format
  2013-01-14 14:09 The printf format GHui
  2013-01-14 14:55 ` Mihai Donțu
  2013-01-14 15:33 ` Ángel González
@ 2013-01-14 16:22 ` Jonathan Wakely
  2 siblings, 0 replies; 4+ messages in thread
From: Jonathan Wakely @ 2013-01-14 16:22 UTC (permalink / raw)
  To: GHui; +Cc: gcc-help

On 14 January 2013 11:29, GHui wrote:
>
> I code the following code.
> --------------------------
> #include <stdio.h>
> int main(int argc,char **argv)
> {
>     float f[2]={4.0, 37.4};
>     printf("%.2f    %.2f\n",f[0],f[1]);
>     printf("%d    %.2f\n",f[0],f[1]);
> }
>
> And it output is following.
> -------------------------
> 4.00    37.40
> -1    4.00
>
> I confuse that f[1] is 4.00 at the second line.

The code has undefined behaviour. Don't try to reason about undefined
behaviour, you should be glad your computer didn't explode.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-01-14 16:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-14 14:09 The printf format GHui
2013-01-14 14:55 ` Mihai Donțu
2013-01-14 15:33 ` Ángel González
2013-01-14 16:22 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).