linux-assembly.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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).