Confused at type conversion

Discussion in 'C Programming' started by 1230987za@gmail.com, Aug 14, 2007.

  1. Guest

    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?
     
    , Aug 14, 2007
    #1
    1. Advertising

  2. 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Aug 14, 2007
    #2
    1. Advertising

  3. 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) <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"
     
    Keith Thompson, Aug 14, 2007
    #3
  4. pete Guest

    Jens Thoms Toerring wrote:
    >
    > 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
     
    pete, Aug 15, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. luna
    Replies:
    1
    Views:
    6,856
  2. ibiza
    Replies:
    2
    Views:
    5,378
    ibiza
    Jan 27, 2006
  3. G. Peter
    Replies:
    15
    Views:
    2,261
    G. Peter
    Jul 1, 2003
  4. Chris
    Replies:
    2
    Views:
    21,373
    Chris
    May 11, 2006
  5. Michal Nazarewicz

    conversion from const type* to type* allowed?

    Michal Nazarewicz, Jan 4, 2007, in forum: C Programming
    Replies:
    13
    Views:
    580
    Eric Sosman
    Jan 5, 2007
Loading...

Share This Page