Forum unknown
· Programming
Trivia
19 messages in this thread
Question for you C gurus — see the following:
VOID
Strange()
{
int i;
i = 1;
i = i++
printf("\n i = %d \n", i);
}
What is the value of i ? Compile it. Try it on other compilers.
Try this one.
VOID
Wierd()
{
int i, j;
i = 1;
j = (i++) + (i++);
printf("\n j = %d i = %d \n", j, i);
{
Again, j and i ? Compile it. Use another compiler.
Any explanations? (I know the answer but I love trick questions)
Ok, I'll play, but you have to explain your answer and be able to cite
reference why you think your answer is right!
Strange()
since ++ binds more tightly than =, and the increment is supposed to be done
immediately after the fetch, then i is first fetched, i is then incremented to
value 2 and then the fetch (1) is stored back into i. Therefore, i = 1 at the
end of the function.
Weird()
() specify order of evaluation. + is evaluated left to right. (i++) or better
yet (1++) fetches a 1 into a register and then increments i to 2. The second
(i++) is evaluated before the addition, so a 2 is fetched and then i is
incremented to 3. The 1 and 2 values that were fetched are added and stored at
j. j = 3, i = 3
Or that is the way it ought to work. So let it be written, so let it be done.
Try it on a couple of different compilers (MegaMax on the ST and Lattice on
the PC produce the same result) but the result is undetermined. Why?
Try it on a couple of different compilers (MegaMax on the ST and Lattice on
the PC produce the same result) but the result is undetermined. Why?
Au contraire… K&R did not specify precedence of the increment operator either
within functions or when a variable appears more than once in an expression. In
other words, it is up to the compiler as to whether the expression
i = i++
produces i or i+1
Every C book I have read warns about this, and it usually forms one of my
arguments against those that claim C as being "the most portable" language.
You are right about the warning, however it is warning about when the store
of the variable is done. The precedence is specifically listed in a standard
table with the ++ a 2nd level precedence and the = a 14th level precedence.
The exact warning in K&R is that: In any expression involving side effects,
there can be subtle dependencies on the order in which varibales taking part
in the expression are stored.
The side effect occurs on how and when the compiler decides to do the store
of i back into i after the increment (or for that fact, where it does the
increment itself). It can legally fetch i (1), do a second fetch of i (1)
and increment the 2nd fetch. It can then store the first fetch back into i
thus completeing the equation. It can then go ahead and store the
incremented value, thus making i = 2.
It can also legally fetch the value of i (1), do the increment in memory
directly on the variable so it now = 2 and then do the store of the fetched
value thus completing the equation but returning a value of 1.
To me, the 2nd is more "logical" and is what my compilers come up with, but
both are legal.
I know, that's why lots of folks don't like C. Personally, I love
it……guess it all depends on your point of view.
All this fooferaw about i = i++ reminds me of the old saw about the doctor
diagnosing a patient
Doctor : Why are you hitting yourself with a hammer?
Patient : It feels so good when I stop!
The question is Why would you do something like that in the first placew?
All this fooferaw about i = i++ reminds me of the old saw about the doctor
diagnosing a patient
Doctor : Why are you hitting yourself with a hammer?
Patient : It feels so good when I stop!
The question is Why would you do something like that in the first placew?
You are right about the warning, however it is warning about when the store
of the variable is done. The precedence is specifically listed in a standard
table with the ++ a 2nd level precedence and the = a 14th level precedence.
The exact warning in K&R is that: In any expression involving side effects,
there can be subtle dependencies on the order in which varibales taking part
in the expression are stored.
The side effect occurs on how and when the compiler decides to do the store
of i back into i after the increment (or for that fact, where it does the
increment itself). It can legally fetch i (1), do a second fetch of i (1)
and increment the 2nd fetch. It can then store the first fetch back into i
thus completeing the equation. It can then go ahead and store the
incremented value, thus making i = 2.
It can also legally fetch the value of i (1), do the increment in memory
directly on the variable so it now = 2 and then do the store of the fetched
value thus completing the equation but returning a value of 1.
To me, the 2nd is more "logical" and is what my compilers come up with, but
both are legal.
I know, that's why lots of folks don't like C. Personally, I love
it……guess it all depends on your point of view.
So a good compiler wouldn't even allow an undefined construct! It should
treat it as a syntax error and leave it at that (or be smart enough to also
point out to the erring programmer that for example "i = i++": "I'll bet you
meant -> i++". But that does require some sophistication from compiler
writers.
No, K&R specifically states that WHEN the store is done is up to the compiler
writer. As such, it is not an error, but a "side-effect" based on when the
store is done. Perfectly legal, but can come up with different values on
different compilers.
What I mean is that such a construct *should* be illegal. If it's "up to the
compiler writer", then it's strictly whim and unreliable by definition. So
why should it be legal?
For an answer to that, I can only guess that Kernighan and Ritchie had
something in mind. Actually, as long as you know what your specific compiler
does, it isn't a problem. Of course, for portability, it can be a problem..
Perhaps under ANSI, there will be a specification for the order of storage,
thus clearing up the ambiguity.
For an answer to that, I can only guess that Kernighan and Ritchie had
something in mind. Actually, as long as you know what your specific compiler
does, it isn't a problem. Of course, for portability, it can be a problem..
Perhaps under ANSI, there will be a specification for the order of storage,
thus clearing up the ambiguity.
What I mean is that such a construct *should* be illegal. If it's "up to the
compiler writer", then it's strictly whim and unreliable by definition. So
why should it be legal?
No, K&R specifically states that WHEN the store is done is up to the compiler
writer. As such, it is not an error, but a "side-effect" based on when the
store is done. Perfectly legal, but can come up with different values on
different compilers.
So a good compiler wouldn't even allow an undefined construct! It should
treat it as a syntax error and leave it at that (or be smart enough to also
point out to the erring programmer that for example "i = i++": "I'll bet you
meant -> i++". But that does require some sophistication from compiler
writers.
Au contraire… K&R did not specify precedence of the increment operator either
within functions or when a variable appears more than once in an expression. In
other words, it is up to the compiler as to whether the expression
i = i++
produces i or i+1
Every C book I have read warns about this, and it usually forms one of my
arguments against those that claim C as being "the most portable" language.
Ok, I'll play, but you have to explain your answer and be able to cite
reference why you think your answer is right!
Strange()
since ++ binds more tightly than =, and the increment is supposed to be done
immediately after the fetch, then i is first fetched, i is then incremented to
value 2 and then the fetch (1) is stored back into i. Therefore, i = 1 at the
end of the function.
Weird()
() specify order of evaluation. + is evaluated left to right. (i++) or better
yet (1++) fetches a 1 into a register and then increments i to 2. The second
(i++) is evaluated before the addition, so a 2 is fetched and then i is
incremented to 3. The 1 and 2 values that were fetched are added and stored at
j. j = 3, i = 3
Or that is the way it ought to work. So let it be written, so let it be done.