This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C Problem?

unsigned char x=1;
x=(x++)<<3;

Using uVision 6.12
Gives answer of 8
It shifts binary 1 left and doesn't increment.
(even when optimization set to level 0)

Using Micorsoft C++ 6.0
Gives answer of 9
It shifts binary 1 left then increments.


I was a little confused with both answers because I was thought that
the increment would happen first because of the ( ) around x++ then
shift left three giving 16 but that's not the case.

This gives me 16 in both Keil and MS.
x=(++x)<<3; works it gives 16


Parents
  • 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;
    
    despite that "no need" parens,
    just to produce evident readability.


    But if we return to original question,
    unsigned char x = 1;
    x = (x++) << 3;
    
    I think that in this case Keil-implementation "more suitable" :),
    because MSVC result '9'
    (accordingly author's original message)
    can be explained only if suppose that 'x++' evaluated after assigning '8' to x.

    As I remember, '=' operation in C:
      LVALUE = EXPRESSION
    
    calculated from right to left.

    I think, this means that
    at first
    EXPRESSION should be COMPLETELY evaluated (with all nested operations, EVEN side-effect operations such as function calls),
    then
    result of expression saved to place
    pointed by LVALUE.


    This is just my common-sense opinion :)

Reply
  • 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;
    
    despite that "no need" parens,
    just to produce evident readability.


    But if we return to original question,
    unsigned char x = 1;
    x = (x++) << 3;
    
    I think that in this case Keil-implementation "more suitable" :),
    because MSVC result '9'
    (accordingly author's original message)
    can be explained only if suppose that 'x++' evaluated after assigning '8' to x.

    As I remember, '=' operation in C:
      LVALUE = EXPRESSION
    
    calculated from right to left.

    I think, this means that
    at first
    EXPRESSION should be COMPLETELY evaluated (with all nested operations, EVEN side-effect operations such as function calls),
    then
    result of expression saved to place
    pointed by LVALUE.


    This is just my common-sense opinion :)

Children
  • unsigned char x = 1;
    x = (x++) << 3;
    "MSVC result '9' ... can be explained only if suppose that 'x++' evaluated after assigning '8' to x."

    Which is what I'd expect from a post increment:

    "x++" means "take the value of x and then, when you've done with it, increment x by one"

    In this case, "when you've done with it" means, "when you've shifted it"

    However, I agree with the consensus that this is ambiguous and best avoided!