Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Confused at type conversion

Reply
Thread Tools

Confused at type conversion

 
 
1230987za@gmail.com
Guest
Posts: n/a
 
      08-14-2007
Hi,
I have the following 2 C files:

f.c:
#include <stdio.h>

void banana_peel(char c, short s, float f){
printf("char c = %c short s = %d float f = %f \n", c, s, f);
}

1.c:
int main(){
short ss = 7;
char cc = 65;
float ff = 10.0;
banana_peel(cc, ss, ff);

return 0;
}

I use gcc to compile them on Linux, and I see the result is :

char c = A short s = 7 float f = 0.000000

I am wondering why the value of f is changed?

When banana_peel is called in main(), ff is converted to double, but
it is still 10.0 right, then why argument f in function banana_peel
gets chopped off?

 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      08-14-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I have the following 2 C files:
> f.c:
> #include <stdio.h>


> void banana_peel(char c, short s, float f){
> printf("char c = %c short s = %d float f = %f \n", c, s, f);
> }


> 1.c:
> int main(){
> short ss = 7;
> char cc = 65;
> float ff = 10.0;
> banana_peel(cc, ss, ff);


> return 0;
> }


> I use gcc to compile them on Linux, and I see the result is :


> char c = A short s = 7 float f = 0.000000


> I am wondering why the value of f is changed?


> When banana_peel is called in main(), ff is converted to double,


Yes, but only since there is no prototype for banana_peel() in
scope in 1.c. If there were one than this conversion to double
wouldn't happen. You're just lucky that the integral promotion
for the first two arguments did not also lead to unexpected
output - on a different architecture that also could happen.

> but it is still 10.0 right, then why argument f in function banana_peel
> gets chopped off?


Your function banana_peel() expects a float as the third argument,
but gets a double, which it then treats as if it would be a float
anyway. I guess you wouldn't surprised if something strange would
be printed out if you would call banana_peel() from main() with an
int as the third argument - integers have a completely different
bit representation than floats. Why do you expect then that it
should be any different when you pass it a double instead of the
expected float? Also floats and doubles have different bit repre-
sentations. The double 10.0 doesn't get chopped off, 0.0 seems to
be what you get when the computer tries to interpret parts of this
double as a float value.
Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      08-14-2007
(E-Mail Removed) writes:
> I have the following 2 C files:
>
> f.c:
> #include <stdio.h>
>
> void banana_peel(char c, short s, float f){
> printf("char c = %c short s = %d float f = %f \n", c, s, f);
> }
>
> 1.c:
> int main(){
> short ss = 7;
> char cc = 65;
> float ff = 10.0;
> banana_peel(cc, ss, ff);
>
> return 0;
> }
>
> I use gcc to compile them on Linux, and I see the result is :
>
> char c = A short s = 7 float f = 0.000000

[...]

As Jens pointed out, the problem is that when the compiler sees the
call to banana_peel(), it has no visible delaration for that function,
so it doesn't know how to call it properly. It falls back to certain
default assumptions which happen to be incorrect in this case.

The solution is to add a declaration.

The simplest way is to combine your f.c and 1.c into a single source
file, but that doesn't scale well to very large programs, and I
suspect the whole point here is to learn how to use multiple source
files.

In general, you want to *define* functions in ".c" files and *declare*
them in ".h" files. Here's my version of your program, with an added
"f.h" file:
========================================
==> f.h <==
void banana_peel(char c, short s, float f);

==> f.c <==
#include <stdio.h>
#include "f.h"

void banana_peel(char c, short s, float f){
printf("char c = %c short s = %d float f = %f \n", c, s, f);
}

==> 1.c <==
#include "f.h"

int main(){
short ss = 7;
char cc = 65;
float ff = 10.0;
banana_peel(cc, ss, ff);

return 0;
}
========================================

#including "f.h" in "f.c" isn't strictly necessary, but it allows the
compiler to check that your declaration is consistent with your
definition.

For more complex cases, where a header might be #included multiple
times (due to headers #including other headers), you want "include
guards", so the header is only processed once for each translation
unit:

#ifndef H_F
#define H_F
void banana_peel(char c, short s, float f);
#endif

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      08-15-2007
Jens Thoms Toerring wrote:
>
> (E-Mail Removed) wrote:
> > I have the following 2 C files:
> > f.c:
> > #include <stdio.h>

>
> > void banana_peel(char c, short s, float f){
> > printf("char c = %c short s = %d float f = %f \n", c, s, f);
> > }

>
> > 1.c:
> > int main(){
> > short ss = 7;
> > char cc = 65;
> > float ff = 10.0;
> > banana_peel(cc, ss, ff);

>
> > return 0;
> > }

>
> > I use gcc to compile them on Linux, and I see the result is :

>
> > char c = A short s = 7 float f = 0.000000

>
> > I am wondering why the value of f is changed?

>
> > When banana_peel is called in main(), ff is converted to double,

>
> Yes, but only since there is no prototype for banana_peel() in
> scope in 1.c. If there were one than this conversion to double
> wouldn't happen. You're just lucky that the integral promotion
> for the first two arguments did not also lead to unexpected
> output - on a different architecture that also could happen.
>
> > but it is still 10.0 right, then why argument f in function banana_peel
> > gets chopped off?

>
> Your function banana_peel() expects a float as the third argument,
> but gets a double, which it then treats as if it would be a float
> anyway. I guess you wouldn't surprised if something strange would
> be printed out if you would call banana_peel() from main() with an
> int as the third argument - integers have a completely different
> bit representation than floats. Why do you expect then that it
> should be any different when you pass it a double instead of the
> expected float? Also floats and doubles have different bit repre-
> sentations. The double 10.0 doesn't get chopped off, 0.0 seems to
> be what you get when the computer tries to interpret parts of this
> double as a float value.


I'll provide a reference:

N869
6.5.2.2 Function calls
[#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.

--
pete
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Type conversion function for user defined type... zaeminkr@gmail.com C++ 1 05-16-2007 09:00 AM
conversion from const type* to type* allowed? Michal Nazarewicz C Programming 13 01-05-2007 01:54 PM
Conversion from type 'DBNull' to type 'String' is not valid Chris ASP .Net 2 05-11-2006 08:20 AM
conversion from type 'DBNull' to type 'float' is not valid ibiza ASP .Net 2 01-27-2006 09:57 PM
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value. luna ASP .Net 1 02-13-2004 01:15 PM



Advertisments