C in X11

Discussion in 'Mac Programming' started by farmerdoug, Sep 27, 2011.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    Two pieces of code. One uses n = n - 1; One uses --n; One works; One doesn't

    Code:
    while( n !=0)
              {
               n = n -1;
               printf(" %d %f %f\n",n,price[l][n+1], price[l][n]);
               }
    
    output
    145 23.900000 24.070000
    144 24.070000 24.110001
    143 24.110001 23.200001
    142 23.200001 23.400000
    141 23.400000 22.940001
    140 22.940001 23.440001
    139 23.440001 24.530001
    138 24.530001 24.709999
    137 24.709999 23.990000
    136 23.990000 24.530001
    135 24.530001 25.129999
    134 25.129999 24.129999
    Code:
     while( n !=0)
              {//n = n -1;
                printf("%d %f %f\n", n,price[l][n], price[l][--n]);
                }
    
    output
    169 53.209999 53.209999
    168 54.799999 54.799999
    167 54.750000 54.750000
    166 54.759998 54.759998
    165 53.880001 53.880001
    164 53.860001 53.860001
    163 53.450001 53.450001
    162 52.930000 52.930000
    161 51.259998 51.259998
    160 51.099998 51.099998
    159 51.349998 51.349998
     
  2. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #2
    The order of evaluation of parameters is not guaranteed to be left to right.

    And what does this have to do with X11?
     
  3. gyorpb, Sep 27, 2011
    Last edited: Sep 27, 2011

    gyorpb macrumors member

    Joined:
    Sep 15, 2011
    Location:
    Amsterdam
    #3
    You don't say what your initial value for n is, nor what the contents of the price array is, so there's no telling exactly why your code isn't doing what you expect it to (or, indeed, what it is that you expect it to do).

    In the latter code snippet, n is decreased after parsing the last statement, price[l][--n], which results in a significantly different printf() statement than in the first snippet.
    Code:
    while (n) {
    	n--;	
    	printf(" %d %f %f\n", n, price[l][n+1], price[l][n]);
    }
    But really, this screams for a for loop:
    Code:
    for (;n;n--) printf(" %d %f %f\n", n, price[l][n+1], price[l][n]);
    .tsooJ
     
  4. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #4
    It has to do with X11 because I don't have the same problem in Xcode.
    What order are you talking about? This doesn't work either.
    printf("%d %f %f\n", n, price[l][--n],price[l][n]);


    I just use the code that works but something seems very strange.
    Thanks
     
  5. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    X11 is a graphical windowing environment. It is not a compiler. It is not an IDE. It makes no sense to say C in X11.
     
  6. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #6
    Robbie: Your right. Sorry. Compiles in Xcode; run from an X11 Terminal.
    gyorpb: thanks. I may try that.
     
  7. ghellquist, Sep 27, 2011
    Last edited: Sep 27, 2011

    ghellquist macrumors regular

    Joined:
    Aug 21, 2011
    Location:
    Stockholm Sweden
    #7
    evaluation order

    The reason is in this par of the line:
    n,price[l][n], price[l][--n]

    The situation you are encountering is that the C compiler is allowed by the language definition to shuffle around exact order of how things are computed.

    You might believe from the text order that things get done the following way:
    print n
    print price[l][n]
    --n
    print price[l][n]

    ( printing is not quite as simple as this )

    But there is absolutely no guarantee for this. The compiler is allowed to do the four things in any order whatsoever. One possibility is this
    --n
    print n
    print price[l][n]
    print price[l][n]

    Another possibility is this
    print n
    print price[l][n]
    print price[l][n]
    --n

    This is an important concept in how C works that will jump up and bit you several times unless you learn the rules of the language. The worst part is that it might differ between how much optimization you apply in the compile stage, so even if you have tested it you might still get the wrong answer.

    // Gunnar
     
  8. jiminaus, Sep 27, 2011
    Last edited: Sep 27, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #8
    Let me quote some stuff from a 2005 draft C spec (because the actual C spec costs).

    Annex C
    In short, don't depend on the order in which arguments are evaluated, don't depend on side-effects in evaluating an argument being visible when evaluating other arguments.
     
  9. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #9
    ghellquist: I've never stop learning.
    thanks.
     
  10. ghellquist macrumors regular

    Joined:
    Aug 21, 2011
    Location:
    Stockholm Sweden
    #10
    No problem.

    Actually, I forgot to mention several important points. Thanks jiminaus for those.

    I believe more can be said in this area. My reaction nowadays is to use extremely conservative coding practices. Writing many short simple lines of code instead of fewer. Relying on the compiler to do optimization of the code, me working on selecting as good algorithms as possible.

    // Gunnar
     
  11. gnasher729, Sep 27, 2011
    Last edited: Sep 27, 2011

    gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #11
    You should at some point learn C programming properly.

    Your code modifies modifies an object (n) and accesses it with intervening sequence point, which invokes undefined behaviour. Undefined behaviour means that anything can happen, including your computer crashing, whatever, and it is your fault, not the compiler's. Pure coincidence that it "worked" in XCode. It might stop working if you switch from 32 to 64 bit, change optimisation settings, change some line of code somewhere nearby or far away, whatever.


    Not only that. The compiler is allowed to completely mess up things. For example reading n the second time while the first change is only half done and getting a nonsense value which then crashes the program. Or deciding that since the code is only legal if n == 0 and the loop is never executed, n must indeed by 0 and compiling accordingly (gcc does stuff like that at high optimisation levels).
     
  12. gyorpb macrumors member

    Joined:
    Sep 15, 2011
    Location:
    Amsterdam
    #12
    The code snippet being discussed here strikes me as typical for a learning process. We've all been through this.

    That said, it is indeed important to adhere to proper coding standards, from the very beginning, even for the small stuff.

    .tsooJ
     
  13. ghellquist macrumors regular

    Joined:
    Aug 21, 2011
    Location:
    Stockholm Sweden
    #13
    Ooh.
    Gnasher729 added even more to my point.

    Adding a typicel "conservative" approach, the first line read as:
    while( n !=0)
    {

    I would always instead use
    while (n > 0)
    {

    as n could somehow, accidentally have been set to a negativt number and that would make the code go wrong.


    // Gunnar
     

Share This Page