* OFF-TOPIC : Confusion about basic C program behaviour
@ 2005-03-10 10:00 Learner
2005-03-10 11:07 ` Stephen Ray
0 siblings, 1 reply; 7+ messages in thread
From: Learner @ 2005-03-10 10:00 UTC (permalink / raw)
To: Linux Kernel Newbie, Assembly Linux
Hi,
I know this is not the correct place to post this
question, but I feel it would be pretty easy for the
kernel gurus to explain this.
TEST CODE
==========
#include <stdio.h>
main()
{
float a1=1.0;
float a2=2.0;
printf(" \n");
printf(" Size of Float > %d \n", sizeof(float) );
printf(" Size of Int > %d \n", sizeof(int) );
printf(" \n");
printf(" CASE 1 : f-f > %f - %f \n\n", a1, a2);
printf(" CASE 2 : f-d > %f - %d \n\n", a1, a2);
printf(" CASE 3 : d-f > %d - %f \n\n", a1, a2);
printf(" CASE 4 : d-d > %d - %d \n\n", a1, a2);
}
OUTPUT :
Size of Float > 4
Size of Int > 4
CASE 1 : f-f > 1.000000 - 2.000000
CASE 2 : f-d > 1.000000 - 0
CASE 3 : d-f > 0 - 0.000000
CASE 4 : d-d > 0 - 1072693248
==================================
The CASE1 & CASE2 & CASE4 outputs are expected.
Any explanation for CASE3 behaviour.
I presume it should behave similar to CASE2 and
print 0 - 2.000000 .
Could somebody please pin-point what is
lacking in my presumtion .
Thanks !
__________________________________
Do you Yahoo!?
Yahoo! Mail - Easier than ever with enhanced search. Learn more.
http://info.mail.yahoo.com/mail_250
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: OFF-TOPIC : Confusion about basic C program behaviour
2005-03-10 10:00 OFF-TOPIC : Confusion about basic C program behaviour Learner
@ 2005-03-10 11:07 ` Stephen Ray
2005-03-10 11:39 ` Bharanidharan S
2005-03-10 11:44 ` Bharanidharan S
0 siblings, 2 replies; 7+ messages in thread
From: Stephen Ray @ 2005-03-10 11:07 UTC (permalink / raw)
To: ruxyz; +Cc: Linux Kernel Newbie, Assembly Linux
Just a thought, but not a particularly educated one. Compiling with
-Wall gives me:
test.c:4: warning: return type defaults to `int'
test.c: In function `main':
test.c:15: warning: int format, double arg (arg 3)
test.c:16: warning: int format, double arg (arg 2)
test.c:18: warning: int format, double arg (arg 2)
test.c:18: warning: int format, double arg (arg 3)
test.c:20: warning: control reaches end of non-void function
Looks like maybe the floats are automatically promoted to doubles before
they are passed to printf. I don't know if that's standard behaviour,
but it seems reasonable. So then in the first case, two 64-bit values
are put on the stack, and two 64-bit values are taken off the stack.
In the second case, two 64-bit values are put on the stack, one 64-bit
value is taken off the stack and presented correctly, and one 64-bit
value has only the first 32 bits read, and misinterpreted as a signed int.
In the third case, two 64-bit values are put on the stack, and the first
32 bits are interpreted as the first signed int, and the second next 64
are interpreted as a double. So case 3 is different from case 2 in that
the double value in case 3 is made up of two halves of two different
doubles, while in case 2 the double is made from an actual double.
Or something like that.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: OFF-TOPIC : Confusion about basic C program behaviour
2005-03-10 11:07 ` Stephen Ray
@ 2005-03-10 11:39 ` Bharanidharan S
2005-03-10 11:44 ` Bharanidharan S
1 sibling, 0 replies; 7+ messages in thread
From: Bharanidharan S @ 2005-03-10 11:39 UTC (permalink / raw)
To: Stephen Ray; +Cc: ruxyz, Linux Kernel Newbie, Assembly Linux
Stephen Ray wrote:
>
> Looks like maybe the floats are automatically promoted to doubles before
> they are passed to printf. I don't know if that's standard behaviour,
> but it seems reasonable. So then in the first case, two 64-bit values
> are put on the stack, and two 64-bit values are taken off the stack.
it seems to be a feature in C.
[ from another mailing list:
https://lists.openafs.org/pipermail/openafs-devel/2003-July/009525.html
]
The text from the ISO 1999 standard in 6.5.2.2 is:
6 If the expression that denotes the called function has a type that
does
not include a prototype, the integer promotions are performed on each
argument, and arguments that have type float are promoted to
double. These are called the default argument promotions. [...]
7 If the expression that denotes the called function has a type that
does
include a prototype, the arguments are implicitly converted, as if by
assignment, to the types of the corresponding parameters, taking the
type of each parameter to be the unqualified version of its declared
type. The ellipsis notation in a function prototype declarator causes
argument type conversion to stop after the last declared parameter.
The
default argument promotions are performed on trailing arguments.
also check glibc's manual (may be out of date ??):
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC478
> In the second case, two 64-bit values are put on the stack, one 64-bit
> value is taken off the stack and presented correctly, and one 64-bit
> value has only the first 32 bits read, and misinterpreted as a signed int.
>
> In the third case, two 64-bit values are put on the stack, and the first
> 32 bits are interpreted as the first signed int, and the second next 64
> are interpreted as a double. So case 3 is different from case 2 in that
> the double value in case 3 is made up of two halves of two different
> doubles, while in case 2 the double is made from an actual double.
>
> Or something like that.
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: OFF-TOPIC : Confusion about basic C program behaviour
2005-03-10 11:07 ` Stephen Ray
2005-03-10 11:39 ` Bharanidharan S
@ 2005-03-10 11:44 ` Bharanidharan S
1 sibling, 0 replies; 7+ messages in thread
From: Bharanidharan S @ 2005-03-10 11:44 UTC (permalink / raw)
To: Stephen Ray; +Cc: Linux Kernel Newbie, Assembly Linux
use this option to prove your hypothesis:
-fshort-double
this would make sizeof(double) = sizeof(float)
by this, stack problems should go away.
but this is not a suffested compiler options because of portability
issues.
Stephen Ray wrote:
>
> Just a thought, but not a particularly educated one. Compiling with
> -Wall gives me:
>
> test.c:4: warning: return type defaults to `int'
> test.c: In function `main':
> test.c:15: warning: int format, double arg (arg 3)
> test.c:16: warning: int format, double arg (arg 2)
> test.c:18: warning: int format, double arg (arg 2)
> test.c:18: warning: int format, double arg (arg 3)
> test.c:20: warning: control reaches end of non-void function
>
> Looks like maybe the floats are automatically promoted to doubles before
> they are passed to printf. I don't know if that's standard behaviour,
> but it seems reasonable. So then in the first case, two 64-bit values
> are put on the stack, and two 64-bit values are taken off the stack.
>
> In the second case, two 64-bit values are put on the stack, one 64-bit
> value is taken off the stack and presented correctly, and one 64-bit
> value has only the first 32 bits read, and misinterpreted as a signed int.
>
> In the third case, two 64-bit values are put on the stack, and the first
> 32 bits are interpreted as the first signed int, and the second next 64
> are interpreted as a double. So case 3 is different from case 2 in that
> the double value in case 3 is made up of two halves of two different
> doubles, while in case 2 the double is made from an actual double.
>
> Or something like that.
>
> --
> Kernelnewbies: Help each other learn about the Linux kernel.
> Archive: http://mail.nl.linux.org/kernelnewbies/
> FAQ: http://kernelnewbies.org/faq/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: OFF-TOPIC : Confusion about basic C program behaviour
@ 2005-03-10 11:54 Learner
2005-03-10 16:23 ` Robert G. Plantz
0 siblings, 1 reply; 7+ messages in thread
From: Learner @ 2005-03-10 11:54 UTC (permalink / raw)
To: Stephen Ray; +Cc: Linux Kernel Newbie, Assembly Linux
Hi Stephen ,
Thanks for catching the float to double promotion
in printf . The man page below confirms this .
#> man 3 printf
<snip>
The conversion specifier
f,F -
The double argument is rounded and converted to
decimal notation in the style [-]ddd.ddd, where the
number of digits after the decimal-point character is
equal to the precision specification. If the
precision is missing, it is taken as 6; if the
precision is explicitly zero, no decimal-point
character appears. If a decimal point
appears, at least one digit appears before it.
<snip>
Just to confirm my understanding, if the code was
changed as below :-
printf(" CASE 3 : d-f > %d - %f \n\n", (int)a1, a2);
only the first 32 bits of the float data a1 would be
put on stack & then the 64 bit float value .
This would be because printf is implemented as a
var args function , so everything is literally copied
to the stack.
Hence, the output would be correct.
Thanks for fixing my basics !
--- Stephen Ray <steve@mrmighty.net> wrote:
> Just a thought, but not a particularly educated one.
> Compiling with
> -Wall gives me:
>
> test.c:4: warning: return type defaults to `int'
> test.c: In function `main':
> test.c:15: warning: int format, double arg (arg 3)
> test.c:16: warning: int format, double arg (arg 2)
> test.c:18: warning: int format, double arg (arg 2)
> test.c:18: warning: int format, double arg (arg 3)
> test.c:20: warning: control reaches end of non-void
> function
>
> Looks like maybe the floats are automatically
> promoted to doubles before
> they are passed to printf. I don't know if that's
> standard behaviour,
> but it seems reasonable. So then in the first case,
> two 64-bit values
> are put on the stack, and two 64-bit values are
> taken off the stack.
>
> In the second case, two 64-bit values are put on the
> stack, one 64-bit
> value is taken off the stack and presented
> correctly, and one 64-bit
> value has only the first 32 bits read, and
> misinterpreted as a signed int.
>
> In the third case, two 64-bit values are put on the
> stack, and the first
> 32 bits are interpreted as the first signed int, and
> the second next 64
> are interpreted as a double. So case 3 is different
> from case 2 in that
> the double value in case 3 is made up of two halves
> of two different
> doubles, while in case 2 the double is made from an
> actual double.
>
> Or something like that.
>
> --
> Kernelnewbies: Help each other learn about the Linux
> kernel.
> Archive:
> http://mail.nl.linux.org/kernelnewbies/
> FAQ: http://kernelnewbies.org/faq/
>
>
__________________________________
Do you Yahoo!?
Yahoo! Mail - Easier than ever with enhanced search. Learn more.
http://info.mail.yahoo.com/mail_250
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: OFF-TOPIC : Confusion about basic C program behaviour
2005-03-10 11:54 Learner
@ 2005-03-10 16:23 ` Robert G. Plantz
0 siblings, 0 replies; 7+ messages in thread
From: Robert G. Plantz @ 2005-03-10 16:23 UTC (permalink / raw)
To: ruxyz; +Cc: Assembly Linux, Stephen Ray, Linux Kernel Newbie
This makes a good case for using explicit type casting.
I urge my students to do that because it explicitly shows what
you are intending to do for the person who has to maintain
your code. In other words, some implicit documentation.
Actually, I like to use separate variables, do my type
casting, then pass the appropriate argument. In these days
where CPUs have floating point and integer units that
can work in parallel, I doubt there would be a performance
hit.
Bob
On Mar 10, 2005, at 3:54 AM, Learner wrote:
> Hi Stephen ,
>
> Thanks for catching the float to double promotion
> in printf . The man page below confirms this .
>
> #> man 3 printf
>
> <snip>
> The conversion specifier
>
> f,F -
>
> The double argument is rounded and converted to
> decimal notation in the style [-]ddd.ddd, where the
> number of digits after the decimal-point character is
> equal to the precision specification. If the
> precision is missing, it is taken as 6; if the
> precision is explicitly zero, no decimal-point
> character appears. If a decimal point
> appears, at least one digit appears before it.
>
> <snip>
>
>
> Just to confirm my understanding, if the code was
> changed as below :-
>
> printf(" CASE 3 : d-f > %d - %f \n\n", (int)a1, a2);
>
> only the first 32 bits of the float data a1 would be
> put on stack & then the 64 bit float value .
>
> This would be because printf is implemented as a
> var args function , so everything is literally copied
> to the stack.
>
> Hence, the output would be correct.
>
> Thanks for fixing my basics !
>
> --- Stephen Ray <steve@mrmighty.net> wrote:
>> Just a thought, but not a particularly educated one.
>> Compiling with
>> -Wall gives me:
>>
>> test.c:4: warning: return type defaults to `int'
>> test.c: In function `main':
>> test.c:15: warning: int format, double arg (arg 3)
>> test.c:16: warning: int format, double arg (arg 2)
>> test.c:18: warning: int format, double arg (arg 2)
>> test.c:18: warning: int format, double arg (arg 3)
>> test.c:20: warning: control reaches end of non-void
>> function
>>
>> Looks like maybe the floats are automatically
>> promoted to doubles before
>> they are passed to printf. I don't know if that's
>> standard behaviour,
>> but it seems reasonable. So then in the first case,
>> two 64-bit values
>> are put on the stack, and two 64-bit values are
>> taken off the stack.
>>
>> In the second case, two 64-bit values are put on the
>> stack, one 64-bit
>> value is taken off the stack and presented
>> correctly, and one 64-bit
>> value has only the first 32 bits read, and
>> misinterpreted as a signed int.
>>
>> In the third case, two 64-bit values are put on the
>> stack, and the first
>> 32 bits are interpreted as the first signed int, and
>> the second next 64
>> are interpreted as a double. So case 3 is different
>> from case 2 in that
>> the double value in case 3 is made up of two halves
>> of two different
>> doubles, while in case 2 the double is made from an
>> actual double.
>>
>> Or something like that.
>>
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: OFF-TOPIC : Confusion about basic C program behaviour
@ 2005-03-14 9:05 Learner
0 siblings, 0 replies; 7+ messages in thread
From: Learner @ 2005-03-14 9:05 UTC (permalink / raw)
To: Gerardo "García" "Peña"
Cc: Linux Kernel Newbie, Assembly Linux
Thank you for the useful link .
--- Gerardo García Peña <gerardo@kung-foo.dhs.org>
wrote:
> Learner wrote:
>
> >Hi,
> >
> > I know this is not the correct place to post this
> >question, but I feel it would be pretty easy for
> the
> >kernel gurus to explain this.
> >
> >TEST CODE
> >==========
> >
> >#include <stdio.h>
> >
> >main()
> >{
> > float a1=1.0;
> > float a2=2.0;
> >
> > printf(" \n");
> > printf(" Size of Float > %d \n", sizeof(float)
> );
> > printf(" Size of Int > %d \n", sizeof(int) );
> > printf(" \n");
> >
> > printf(" CASE 1 : f-f > %f - %f \n\n", a1, a2);
> > printf(" CASE 2 : f-d > %f - %d \n\n", a1, a2);
> > printf(" CASE 3 : d-f > %d - %f \n\n", a1, a2);
> > printf(" CASE 4 : d-d > %d - %d \n\n", a1, a2);
> >}
> >
> >OUTPUT :
> >
> > Size of Float > 4
> > Size of Int > 4
> >
> > CASE 1 : f-f > 1.000000 - 2.000000
> >
> > CASE 2 : f-d > 1.000000 - 0
> >
> > CASE 3 : d-f > 0 - 0.000000
> >
> > CASE 4 : d-d > 0 - 1072693248
> >
> >==================================
> >
> >The CASE1 & CASE2 & CASE4 outputs are expected.
> >
> > Any explanation for CASE3 behaviour.
> > I presume it should behave similar to CASE2 and
> >print 0 - 2.000000 .
> >
> > Could somebody please pin-point what is
> >lacking in my presumtion .
> >
> >Thanks !
> >
> >
> >
> I believe this happens because float is promoted to
> double when it is
> passed as an arg... so you should think that double
> = 8 and int = 4.
>
> I have been googling and I have found this:
>
>
>
http://www-ccs.ucsd.edu/c/function.html#argument%20promotion
>
>
__________________________________
Do you Yahoo!?
Yahoo! Small Business - Try our new resources site!
http://smallbusiness.yahoo.com/resources/
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2005-03-14 9:05 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-10 10:00 OFF-TOPIC : Confusion about basic C program behaviour Learner
2005-03-10 11:07 ` Stephen Ray
2005-03-10 11:39 ` Bharanidharan S
2005-03-10 11:44 ` Bharanidharan S
-- strict thread matches above, loose matches on Subject: below --
2005-03-10 11:54 Learner
2005-03-10 16:23 ` Robert G. Plantz
2005-03-14 9:05 Learner
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 NNTP newsgroup(s).