distant compilation and float literals

Discussion in 'C Programming' started by Christian, Oct 13, 2006.

  1. Christian

    Christian Guest

    Hi,

    I have a small problem about distant compilation and float literals.
    Here is my program :

    #include <stdio.h>
    void main() {
    float f;
    double d;
    f = 0.5;
    printf("f=%f\n", f);
    printf("0.5=%f\n", 0.5);
    printf("0.5f=%f\n", 0.5f);
    printf("0.9=%f\n", 0.9);
    printf("1.9=%f\n", 1.9);
    d = 0.5;
    printf("d0.5=%f\n", d);
    printf("1.0/2.0=%f\n", 1.0 / 2.0);
    }

    I compile on HP-UX 11.11 et then execute it :
    #/usr/bin/cc c.c
    #a.out
    f=0.500000
    0.5=0.500000
    0.5f=0.500000
    0.9=0.900000
    1.9=1.900000
    d0.5=0.500000
    1.0/2.0=0.500000

    Every thing is ok.

    Then I compile it again from a distant solaris machine.
    solaris#rsh machineHP /usr/bin/cc c.c

    and execute it again on HP :
    #a.out
    f=0.000000
    0.5=0.000000
    0.5f=0.000000
    0.9=0.000000
    1.9=1.000000
    d0.5=0.000000
    1.0/2.0=0.500000

    It seems thant every float literals are rounded to integer.

    How can I avoid this ?

    Thank you for your help.
     
    Christian, Oct 13, 2006
    #1
    1. Advertising

  2. Christian said:

    > Hi,
    >
    > I have a small problem about distant compilation and float literals.
    > Here is my program :
    >
    > #include <stdio.h>
    > void main() {


    In C, main returns int. The best way to prototype main (when you don't care
    about command line arguments) is:

    int main(void)

    The main function has never, ever been specified either by ISO or K&R as
    returning anything but int. Please, get the program's entry point right;
    it's the least you can do. If you get it wrong, the program's behaviour is
    undefined. I'm not saying that's what caused your weird output on Solaris,
    but it's not impossible.

    > float f;
    > double d;
    > f = 0.5;
    > printf("f=%f\n", f);
    > printf("0.5=%f\n", 0.5);
    > printf("0.5f=%f\n", 0.5f);
    > printf("0.9=%f\n", 0.9);
    > printf("1.9=%f\n", 1.9);
    > d = 0.5;
    > printf("d0.5=%f\n", d);
    > printf("1.0/2.0=%f\n", 1.0 / 2.0);


    The main function returns int, so let's return an int:

    return 0;

    > }
    >
    > I compile on HP-UX 11.11 et then execute it :

    <snip>
    >
    > Every thing is ok.


    Okay.

    >
    > Then I compile it again from a distant solaris machine.
    > solaris#rsh machineHP /usr/bin/cc c.c
    >
    > and execute it again on HP :
    > #a.out
    > f=0.000000
    > 0.5=0.000000
    > 0.5f=0.000000
    > 0.9=0.000000
    > 1.9=1.000000
    > d0.5=0.000000
    > 1.0/2.0=0.500000
    >
    > It seems thant every float literals are rounded to integer.


    But not the calculated value. Yes, that is strange. (Note that in fact these
    are doubles, not floats, by the time they hit printf. They are promoted on
    the way.)

    >
    > How can I avoid this ?


    On the face of it, the code (apart from your return type error) looks okay,
    so if you are reporting the facts faithfully it looks like this might be an
    implementation issue on Solaris. Perhaps you are invoking it incorrectly?

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Oct 13, 2006
    #2
    1. Advertising

  3. Christian

    lxrocks Guest

    I don't know HP C-compiler but my guess is that 'rsh' may not set your
    environment up in the same way as telnet or ssh, which is probably
    causing a difference.

    I have seen cases in unix/linux where inetd gets manually restarted by a
    sysadmin without the proper environment and inetd inherits the
    sysadmin's environment, which subsequent rsh logins inherit too.

    Good Luck!



    Christian wrote:
    > Hi,
    >
    > I have a small problem about distant compilation and float literals.
    > Here is my program :
    >
    > #include <stdio.h>
    > void main() {
    > float f;
    > double d;
    > f = 0.5;
    > printf("f=%f\n", f);
    > printf("0.5=%f\n", 0.5);
    > printf("0.5f=%f\n", 0.5f);
    > printf("0.9=%f\n", 0.9);
    > printf("1.9=%f\n", 1.9);
    > d = 0.5;
    > printf("d0.5=%f\n", d);
    > printf("1.0/2.0=%f\n", 1.0 / 2.0);
    > }
    >
    > I compile on HP-UX 11.11 et then execute it :
    > #/usr/bin/cc c.c
    > #a.out
    > f=0.500000
    > 0.5=0.500000
    > 0.5f=0.500000
    > 0.9=0.900000
    > 1.9=1.900000
    > d0.5=0.500000
    > 1.0/2.0=0.500000
    >
    > Every thing is ok.
    >
    > Then I compile it again from a distant solaris machine.
    > solaris#rsh machineHP /usr/bin/cc c.c
    >
    > and execute it again on HP :
    > #a.out
    > f=0.000000
    > 0.5=0.000000
    > 0.5f=0.000000
    > 0.9=0.000000
    > 1.9=1.000000
    > d0.5=0.000000
    > 1.0/2.0=0.500000
    >
    > It seems thant every float literals are rounded to integer.
    >
    > How can I avoid this ?
    >
    > Thank you for your help.
     
    lxrocks, Oct 13, 2006
    #3
  4. Christian wrote:
    > Hi,
    >
    > I have a small problem about distant compilation and float literals.
    > Here is my program :
    >
    > #include <stdio.h>
    > void main() {
    > float f;
    > double d;
    > f = 0.5;
    > printf("f=%f\n", f);
    > printf("0.5=%f\n", 0.5);
    > printf("0.5f=%f\n", 0.5f);
    > printf("0.9=%f\n", 0.9);
    > printf("1.9=%f\n", 1.9);
    > d = 0.5;
    > printf("d0.5=%f\n", d);
    > printf("1.0/2.0=%f\n", 1.0 / 2.0);
    > }
    >
    > I compile on HP-UX 11.11 et then execute it :
    > #/usr/bin/cc c.c
    > #a.out
    > f=0.500000
    > 0.5=0.500000
    > 0.5f=0.500000
    > 0.9=0.900000
    > 1.9=1.900000
    > d0.5=0.500000
    > 1.0/2.0=0.500000
    >
    > Every thing is ok.
    >
    > Then I compile it again from a distant solaris machine.
    > solaris#rsh machineHP /usr/bin/cc c.c
    >
    > and execute it again on HP :
    > #a.out
    > f=0.000000
    > 0.5=0.000000
    > 0.5f=0.000000
    > 0.9=0.000000
    > 1.9=1.000000
    > d0.5=0.000000
    > 1.0/2.0=0.500000
    >
    > It seems thant every float literals are rounded to integer.
    >
    > How can I avoid this ?
    >
    > Thank you for your help.


    [Note that the values are not being rounded but truncated]

    Odd. As pointed out elsethread, void main is a mistake,
    but I can't see it causing this problem.

    Three possiblities:

    The compiler on the remote machine is not
    producing executables that are suitable for
    your local machine. Have you tried executing
    on the remote machine?

    The a.out you are executing is not the a.out
    you think you are executing ( maybe because
    the PATH is being changed behind your back).
    Have you tried using full path names?

    You are not in fact reporting what actually happened,
    but what you think actually happened.

    The problem does not appear to be C related (any more
    than this post is english related).

    - William Hughes
     
    William Hughes, Oct 13, 2006
    #4
  5. Christian

    Christian Guest

    William Hughes a écrit :

    > Three possiblities:
    >
    > The compiler on the remote machine is not
    > producing executables that are suitable for
    > your local machine. Have you tried executing
    > on the remote machine?


    I always use the compiler on the HP machine. I only launch it from the
    remote (solaris) one.

    >
    > The a.out you are executing is not the a.out
    > you think you are executing ( maybe because
    > the PATH is being changed behind your back).
    > Have you tried using full path names?

    yes

    And I changed the function to "int main(void)".

    Same pb.
     
    Christian, Oct 13, 2006
    #5
  6. Re: distant compilation and float literals . The solution

    Here is the solution :

    solaris#rsh sir01hp "setenv LANG C ; /usr/bin/cc c.c"

    Christian a écrit :

    > Hi,
    >
    > I have a small problem about distant compilation and float literals.
    > Here is my program :
    >
    > #include <stdio.h>
    > void main() {
    > float f;
    > double d;
    > f = 0.5;
    > printf("f=%f\n", f);
    > printf("0.5=%f\n", 0.5);
    > printf("0.5f=%f\n", 0.5f);
    > printf("0.9=%f\n", 0.9);
    > printf("1.9=%f\n", 1.9);
    > d = 0.5;
    > printf("d0.5=%f\n", d);
    > printf("1.0/2.0=%f\n", 1.0 / 2.0);
    > }
    >
    > I compile on HP-UX 11.11 et then execute it :
    > #/usr/bin/cc c.c
    > #a.out
    > f=0.500000
    > 0.5=0.500000
    > 0.5f=0.500000
    > 0.9=0.900000
    > 1.9=1.900000
    > d0.5=0.500000
    > 1.0/2.0=0.500000
    >
    > Every thing is ok.
    >
    > Then I compile it again from a distant solaris machine.
    > solaris#rsh machineHP /usr/bin/cc c.c
    >
    > and execute it again on HP :
    > #a.out
    > f=0.000000
    > 0.5=0.000000
    > 0.5f=0.000000
    > 0.9=0.000000
    > 1.9=1.000000
    > d0.5=0.000000
    > 1.0/2.0=0.500000
    >
    > It seems thant every float literals are rounded to integer.
    >
    > How can I avoid this ?
    >
    > Thank you for your help.
     
    Christian MOENNE-LOCCOZ, Oct 23, 2006
    #6
  7. Re: distant compilation and float literals . The solution

    [Top posting corrected]

    Christian MOENNE-LOCCOZ wrote: >>
    > Christian a écrit : >
    >
    > > Hi,
    > >
    > > I have a small problem about distant compilation and float literals.
    > > Here is my program :
    > >
    > > #include <stdio.h>
    > > void main() {
    > > float f;
    > > double d;
    > > f = 0.5;
    > > printf("f=%f\n", f);
    > > printf("0.5=%f\n", 0.5);
    > > printf("0.5f=%f\n", 0.5f);
    > > printf("0.9=%f\n", 0.9);
    > > printf("1.9=%f\n", 1.9);
    > > d = 0.5;
    > > printf("d0.5=%f\n", d);
    > > printf("1.0/2.0=%f\n", 1.0 / 2.0);
    > > }
    > >
    > > I compile on HP-UX 11.11 et then execute it :
    > > #/usr/bin/cc c.c
    > > #a.out
    > > f=0.500000
    > > 0.5=0.500000
    > > 0.5f=0.500000
    > > 0.9=0.900000
    > > 1.9=1.900000
    > > d0.5=0.500000
    > > 1.0/2.0=0.500000
    > >
    > > Every thing is ok.
    > >
    > > Then I compile it again from a distant solaris machine.
    > > solaris#rsh machineHP /usr/bin/cc c.c
    > >
    > > and execute it again on HP :
    > > #a.out
    > > f=0.000000
    > > 0.5=0.000000
    > > 0.5f=0.000000
    > > 0.9=0.000000
    > > 1.9=1.000000
    > > d0.5=0.000000
    > > 1.0/2.0=0.500000
    > >
    > > It seems thant every float literals are rounded to integer.
    > >
    > > How can I avoid this ?
    > >
    > > Thank you for your help.


    > Here is the solution :
    >
    > solaris#rsh sir01hp "setenv LANG C ; /usr/bin/cc c.c"
    >



    Kudos to lxrocks who correctly noted that rsh might
    not set up the environment as expected. Presumably, if
    LANG is not defined or is defined to something other than C,
    the cc program does not compile ANSI C but something
    else. Were you able to discover what cc was in fact doing?

    - William Hughes
     
    William Hughes, Oct 23, 2006
    #7
  8. Re: distant compilation and float literals . The solution

    "William Hughes" <> writes:

    > [Top posting corrected]
    >
    > Christian MOENNE-LOCCOZ wrote: >>
    >> Christian a écrit : >
    >>
    >> > Hi,
    >> >
    >> > I have a small problem about distant compilation and float literals.
    >> > Here is my program :
    >> >
    >> > #include <stdio.h>
    >> > void main() {
    >> > float f;
    >> > double d;
    >> > f = 0.5;
    >> > printf("f=%f\n", f);
    >> > printf("0.5=%f\n", 0.5);
    >> > printf("0.5f=%f\n", 0.5f);
    >> > printf("0.9=%f\n", 0.9);
    >> > printf("1.9=%f\n", 1.9);
    >> > d = 0.5;
    >> > printf("d0.5=%f\n", d);
    >> > printf("1.0/2.0=%f\n", 1.0 / 2.0);
    >> > }
    >> >
    >> > I compile on HP-UX 11.11 et then execute it :
    >> > #/usr/bin/cc c.c
    >> > #a.out
    >> > f=0.500000
    >> > 0.5=0.500000
    >> > 0.5f=0.500000
    >> > 0.9=0.900000
    >> > 1.9=1.900000
    >> > d0.5=0.500000
    >> > 1.0/2.0=0.500000
    >> >
    >> > Every thing is ok.
    >> >
    >> > Then I compile it again from a distant solaris machine.
    >> > solaris#rsh machineHP /usr/bin/cc c.c
    >> >
    >> > and execute it again on HP :
    >> > #a.out
    >> > f=0.000000
    >> > 0.5=0.000000
    >> > 0.5f=0.000000
    >> > 0.9=0.000000
    >> > 1.9=1.000000
    >> > d0.5=0.000000
    >> > 1.0/2.0=0.500000
    >> >
    >> > It seems thant every float literals are rounded to integer.
    >> >
    >> > How can I avoid this ?
    >> >
    >> > Thank you for your help.

    >
    >> Here is the solution :
    >>
    >> solaris#rsh sir01hp "setenv LANG C ; /usr/bin/cc c.c"
    >>

    >
    >
    > Kudos to lxrocks who correctly noted that rsh might
    > not set up the environment as expected. Presumably, if
    > LANG is not defined or is defined to something other than C,
    > the cc program does not compile ANSI C but something
    > else. Were you able to discover what cc was in fact doing?


    Wild guess, the locale use a coma as decimal separator, the compiler has a
    call to setlocale, use strtod to do the conversion and don't very the
    result, assuming that the lexer did his job correctly. The lexer did is
    job correctly but strtod is locale dependant and so stop at the point.

    Yours,

    --
    Jean-Marc
     
    Jean-Marc Bourguet, Oct 23, 2006
    #8
  9. Re: distant compilation and float literals . The solution

    Jean-Marc Bourguet wrote:
    > "William Hughes" <> writes:
    >
    > > [Top posting corrected]
    > >
    > > Christian MOENNE-LOCCOZ wrote: >>
    > >> Christian a écrit : >
    > >>
    > >> > Hi,
    > >> >
    > >> > I have a small problem about distant compilation and float literals.
    > >> > Here is my program :
    > >> >
    > >> > #include <stdio.h>
    > >> > void main() {
    > >> > float f;
    > >> > double d;
    > >> > f = 0.5;
    > >> > printf("f=%f\n", f);
    > >> > printf("0.5=%f\n", 0.5);
    > >> > printf("0.5f=%f\n", 0.5f);
    > >> > printf("0.9=%f\n", 0.9);
    > >> > printf("1.9=%f\n", 1.9);
    > >> > d = 0.5;
    > >> > printf("d0.5=%f\n", d);
    > >> > printf("1.0/2.0=%f\n", 1.0 / 2.0);
    > >> > }
    > >> >
    > >> > I compile on HP-UX 11.11 et then execute it :
    > >> > #/usr/bin/cc c.c
    > >> > #a.out
    > >> > f=0.500000
    > >> > 0.5=0.500000
    > >> > 0.5f=0.500000
    > >> > 0.9=0.900000
    > >> > 1.9=1.900000
    > >> > d0.5=0.500000
    > >> > 1.0/2.0=0.500000
    > >> >
    > >> > Every thing is ok.
    > >> >
    > >> > Then I compile it again from a distant solaris machine.
    > >> > solaris#rsh machineHP /usr/bin/cc c.c
    > >> >
    > >> > and execute it again on HP :
    > >> > #a.out
    > >> > f=0.000000
    > >> > 0.5=0.000000
    > >> > 0.5f=0.000000
    > >> > 0.9=0.000000
    > >> > 1.9=1.000000
    > >> > d0.5=0.000000
    > >> > 1.0/2.0=0.500000
    > >> >
    > >> > It seems thant every float literals are rounded to integer.
    > >> >
    > >> > How can I avoid this ?
    > >> >
    > >> > Thank you for your help.

    > >
    > >> Here is the solution :
    > >>
    > >> solaris#rsh sir01hp "setenv LANG C ; /usr/bin/cc c.c"
    > >>

    > >
    > >
    > > Kudos to lxrocks who correctly noted that rsh might
    > > not set up the environment as expected. Presumably, if
    > > LANG is not defined or is defined to something other than C,
    > > the cc program does not compile ANSI C but something
    > > else. Were you able to discover what cc was in fact doing?

    >
    > Wild guess, the locale use a coma as decimal separator, the compiler has a
    > call to setlocale, use strtod to do the conversion and don't very the
    > result, assuming that the lexer did his job correctly. The lexer did is
    > job correctly but strtod is locale dependant and so stop at the point.
    >


    Does setlocale take effect during compilation?

    Assuming that it does,
    if we set a comma as the decimal separator, shouldn't

    f=0.5;

    produce a syntax error (i.e. is it acceptable for the compiler to toss
    "0.5" at a function and use the result, without checking that the
    entire string has been used) ?

    - William Hughes
     
    William Hughes, Oct 23, 2006
    #9
  10. Re: distant compilation and float literals . The solution

    "William Hughes" <> writes:

    >> Wild guess, the locale use a coma as decimal separator, the compiler has a
    >> call to setlocale, use strtod to do the conversion and don't very the

    s/very/verify/
    >> result, assuming that the lexer did his job correctly. The lexer did is
    >> job correctly but strtod is locale dependant and so stop at the point.
    >>

    >
    > Does setlocale take effect during compilation?


    My guess is that the *compiler* called setlocale (for handling messages and
    character set).

    > Assuming that it does, if we set a comma as the decimal separator,
    > shouldn't
    >
    > f=0.5;
    > produce a syntax error (i.e. is it acceptable for the compiler to toss
    > "0.5" at a function and use the result, without checking that the entire
    > string has been used) ?


    My guess was that the lexer correctly ignored the setting of decimal
    separator in the locale and returned the string "0.5". Then sometimes
    after, the compiler needed it to be evaluated and so strtod was called
    without checking the result of strtod as the lexer would not have returned
    something which was not a valid representation.

    Assuming my guess is correct, there is a bug in the compiler. And the bug
    can well have been introduced when adding localization to the compiler, in
    which case the assumption that strtod call could have been valid for years.

    Yours,

    --
    Jean-Marc
     
    Jean-Marc Bourguet, Oct 23, 2006
    #10
  11. Re: distant compilation and float literals . The solution

    Jean-Marc Bourguet wrote:
    > "William Hughes" <> writes:
    >
    > >> Wild guess, the locale use a coma as decimal separator, the compiler has a
    > >> call to setlocale, use strtod to do the conversion and don't very the

    > s/very/verify/
    > >> result, assuming that the lexer did his job correctly. The lexer did is
    > >> job correctly but strtod is locale dependant and so stop at the point.
    > >>

    > >
    > > Does setlocale take effect during compilation?

    >
    > My guess is that the *compiler* called setlocale (for handling messages and
    > character set).


    Ok. Point taken. Can the compiler do this and remain conforming?

    >
    > > Assuming that it does, if we set a comma as the decimal separator,
    > > shouldn't
    > >
    > > f=0.5;
    > > produce a syntax error (i.e. is it acceptable for the compiler to toss
    > > "0.5" at a function and use the result, without checking that the entire
    > > string has been used) ?

    >
    > My guess was that the lexer correctly ignored the setting of decimal
    > separator in the locale and returned the string "0.5". Then sometimes
    > after, the compiler needed it to be evaluated and so strtod was called
    > without checking the result of strtod as the lexer would not have returned
    > something which was not a valid representation.
    >
    > Assuming my guess is correct, there is a bug in the compiler. And the bug
    > can well have been introduced when adding localization to the compiler, in
    > which case the assumption that strtod call could have been valid for years.
    >


    Indeed. Seems like a good guess (it certainly explains the observed
    behaviour, and seems plausible, moreso than the semi-compatible
    floating point formats that is the best guess I have been able
    to come up with).. On the other hand "LANG" would
    be a poor choice of environment variable to set to locale. My guess
    is that there is something a little more indirect, mabye if LANG is not
    set the compiler defaults to HP-C, which does not use the C
    locale by default.

    - William Hughes
     
    William Hughes, Oct 23, 2006
    #11
  12. Re: distant compilation and float literals . The solution

    "William Hughes" <> writes:

    > Jean-Marc Bourguet wrote:
    >> "William Hughes" <> writes:
    >>
    >> >> Wild guess, the locale use a coma as decimal separator, the compiler has a
    >> >> call to setlocale, use strtod to do the conversion and don't very the

    >> s/very/verify/
    >> >> result, assuming that the lexer did his job correctly. The lexer did is
    >> >> job correctly but strtod is locale dependant and so stop at the point.
    >> >>
    >> >
    >> > Does setlocale take effect during compilation?

    >>
    >> My guess is that the *compiler* called setlocale (for handling messages and
    >> character set).

    >
    > Ok. Point taken. Can the compiler do this and remain conforming?


    Well, it's somewhat meaningfull to use the locale to determine in which
    charset the code has been written and to choose the langage in which
    outputting error messages (but then I've more trouble to understand error
    message in french than in english, translations seem sometimes done by a
    computer and never have been reviewed by a human). I'd provide a way to
    overwrite the charset on the command line so that build don't depend on the
    user environment. What is not conforming is depending on the locale to
    evaluate floating point numbers in C code.

    >> Assuming my guess is correct, there is a bug in the compiler. And the bug
    >> can well have been introduced when adding localization to the compiler, in
    >> which case the assumption that strtod call could have been valid for years.
    >>

    >
    > Indeed. Seems like a good guess (it certainly explains the observed
    > behaviour, and seems plausible, moreso than the semi-compatible
    > floating point formats that is the best guess I have been able
    > to come up with).. On the other hand "LANG" would
    > be a poor choice of environment variable to set to locale. My guess
    > is that there is something a little more indirect, mabye if LANG is not
    > set the compiler defaults to HP-C, which does not use the C
    > locale by default.


    Posix defines a bunch of environement variables to control locale
    behaviour, LANG is one of them (the one which has the less priority BTW).

    Yours,

    --
    Jean-Marc
     
    Jean-Marc Bourguet, Oct 23, 2006
    #12
    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. John Goche
    Replies:
    8
    Views:
    16,550
  2. puzzlecracker
    Replies:
    4
    Views:
    489
    Sharad Kala
    Feb 14, 2005
  3. bd
    Replies:
    0
    Views:
    660
  4. Carsten Fuchs
    Replies:
    45
    Views:
    1,628
    James Kanze
    Oct 8, 2009
  5. Noah Roberts
    Replies:
    2
    Views:
    464
    Noah Roberts
    Mar 22, 2011
Loading...

Share This Page