unsigned char x=1; x=(x++)<<3;
x=(++x)<<3; works it gives 16
Keil does have some problems with the pre- and post- increment/decrement operators when used within a more complicated expression. However, the value of the expression "x++" is x; the increment is not done until after the expression is evaluated - hence post increment! So
(x++)<<3
(x)<<3; x += 1
Between consecutive "sequence points", an object's value can be modified only once by an expression. The only "sequence point" in your line of code is the ";". This means x is modified twice. Once by the =, and once by the ++. This code has no well defined meaning. It is not surprising that different implementations gave different answers.
Since this equation produces undefined behavior, there is no right answer IMHO. See:
http://www.eskimo.com/~scs/C-faq/q3.3.html
x = x + 1 << 3;
To Keil Discussion Forum site: Add the following suggestion to your "Tips for Posting Measages". If you type an URL like
<pre>TheUrl</pre>
Actually, there is no need to use the <pre> and </pre> tags for URLs at all - the forum automatically makes URLs clickable (as it says in the Tips). It seems that it's this automatic conversion to a link which has gone wrong - it's caught the closing </pre> tag inside the closing </a> link tag! So yes, a space (or newline?) before the </pre> would probably have fixed it.
Sorry about that, I didn't mean to use the pre tag at all. - Mark
>Keil does have some problems with the pre- and >post- increment/decrement operators when used >within a more complicated expression Which problems your take in mind ? >(x++)<<3 >is equivalent to >(x)<<3; x += 1 >and it seems that MSVC has the "right" >answer. This is not exactly the same as original qiestion:
unsigned char x = 1; x=(x++) << 3;
unsigned char x = 1; unsigned char tmp; tmp = x; // get old value of 'x' x = x + 1; // x++ x = (tmp << 3); // Assign('=') have lowest priority
See "The C Programming Language", second edition, section 2.12. K&R have quite a lot to say about this sort of problem including: "One unhappy situation is typified by the statement
a[i] = i++;
Please see http://www.eskimo.com/~scs/C-faq/q3.3.html
x = (x++) << 3;
Mark, thanks for good point: http://www.eskimo.com/~scs/C-faq/q3.3.html http://www.eskimo.com/~scs/C-faq/top.html It is a good place to understand why I intuitively avoid some ambiguous C-constructions :) On the other side, this is a 'style' quiestion. For example, in your case I always write as
x = (x + 1) << 3;
unsigned char x = 1; x = (x++) << 3;
LVALUE = EXPRESSION
This thread is well and truly dead, but I've found another situation where an ambiguity similar to this can trip you up:
a[b++] = c;
Welcome to the wonderful club comprised of those bitten by race conditions. We'll get you your membership card tomorrow. In point of fact, there doesn't need to be an index in this expression to cause a problem. Essentially, if you have interrupt-driven code, you must imagine that any instruction that is not "atomic" (i.e. completed without interruption) can be stopped in the middle. Thus, something as simple as
a = b;
This ambiguity is actually rather unrelated to the one discussed here earlier. The earlier examples had much more serious problems than yours --- they produced undefined behaviour, which means the compiler is allowed to explode the processor 123*pi hours after noon of the Tuesday following last year's Hallowe'en, if it so pleases. Your example is broken only because introduced an additional ingredient into the game: multiple (pseudo-)concurrent threads of control. C doesn't even try to address that type of problem in the language itself, beyond controlling access to individual objects via the volatile qualifier.