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
  • >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;
    

    is equivalent to

    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
    
    

    So, right answer is 'x==8' after all.



Reply
  • >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;
    

    is equivalent to

    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
    
    

    So, right answer is 'x==8' after all.



Children
  • Please see

    http://www.eskimo.com/~scs/C-faq/q3.3.html

    x = (x++) << 3;
    not only are the parens useless since ++ is much higher precedence than << but the resultant value assigned to x is up to the implementation (compiler) you are using. This sort of equation should be written as
    x = x + 1 << 3;
    Let the compiler figure out that +1 means INC.

    Regards,

    - Mark

  • 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 :)

  • 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!