Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

farmerdoug

macrumors 6502a
Original poster
Sep 16, 2008
541
0
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
 
The order of evaluation of parameters is not guaranteed to be left to right.

And what does this have to do with X11?
 
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
 
Last edited:
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
 
Robbie: Your right. Sorry. Compiles in Xcode; run from an X11 Terminal.
gyorpb: thanks. I may try that.
 
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
 
Last edited:
Let me quote some stuff from a 2005 draft C spec (because the actual C spec costs).

The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. (A summary of the sequence points is given in annex C.)

Annex C
The following are the sequence points described in 5.1.2.3:
- The call to a function, after the arguments have been evaluated (6.5.2.2).

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.
 
Last edited:
ghellquist: I've never stop learning.
thanks.
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
 
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

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.


But there is absolutely no guarantee for this. The compiler is allowed to do the four things in any order whatsoever.

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).
 
Last edited:
You should at some point learn C programming properly.
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
 
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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.