Be cautious when iterating bit-shifts

Discussion in 'C Programming' started by geo, Nov 16, 2009.

  1. geo

    geo Guest

    #include <stdio.h>
    int main()
    { int x=2048;
    printf("%d\n",x);
    printf("%d\n",((x<<2)>>2) );
    printf("%d\n", (x<<2)>>2 );
    printf("%d\n",((x<<2)>>2)-x );
    printf("%d\n", (x<<2)>>2 -x );
    }

    Can you predict what five integers
    will result from compiling and running
    the above program?
    Will all compilers give the same results?
     
    geo, Nov 16, 2009
    #1
    1. Advertisements

  2. geo

    Noob Guest

    $ cat foo.c
    #include <stdio.h>
    int main(void)
    {
    int x=2048;
    printf("%d\n",x);
    printf("%d\n",((x<<2)>>2) );
    printf("%d\n", (x<<2)>>2 );
    printf("%d\n",((x<<2)>>2)-x );
    printf("%d\n", (x<<2)>>2 -x );
    return 0;
    }

    $ gcc -std=c89 -pedantic -Wall -Wextra foo.c
    foo.c: In function 'main':
    foo.c:9: warning: suggest parentheses around + or - inside shift

    ===> NB gcc's suggestion <===

    $ ./a.out
    2048
    2048
    2048
    0
    2048

    INT_MAX must be at least 32767.
    2048 << 2 equals 8192, thus x << 2 is always well-defined.
    Let y = x << 2

    You're considering
    1. (y >> 2)
    2. y >> 2
    3. (y >> 2) - x
    4. y >> 2 - x

    1. and 2. are obviously equivalent, and equal to x.
    3. is equivalent to x - x i.e. 0.
    4. is equivalent to y >> (2-x) which is undefined.

    Regards.
     
    Noob, Nov 16, 2009
    #2
    1. Advertisements

  3. geo

    Eric Sosman Guest

    No: Undefined behavior is not predictable. Not on the
    basis of the C language, at any rate, although it might be
    possible to predict the outcome for a given implementation.
    Unlikely: Undefined behavior is not guaranteed to be
    consistent.
     
    Eric Sosman, Nov 16, 2009
    #3
  4. geo

    Phil Carmody Guest

    Don't mix bit-wise operations with arithmetic operations
    unless you have an over-riding need to.

    << >> & | ^: fine
    * / % + - : fine

    Cross-pollination leads to mutants.

    Phil
     
    Phil Carmody, Nov 19, 2009
    #4
  5. geo

    Phil Carmody Guest

    Absolutely, "(1u<<n)-1" has great longevity for a reason.

    Phil
     
    Phil Carmody, Nov 21, 2009
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.