Home
Fractals
Tutorials
Books
Archive
My blog
My LinkedIn Profile

BOOKS i'm reading

Cryptography engineering, Niels Ferguson, Bruce Schneier, Tadayoshi Kohno, ISBN: 9780470474242
Advanced Programming in the UNIX(R) Environment (2nd Edition), W. Richard Stevens, Stephen A. Rago, ISBN:0201433079
Trading For a Living, Alexander Elder, ISBN:0471592242

mailto:olivier@olivierlanglois.net

shift operator undefined behavior

04/12/08

Permalink 03:22:31 pm, by lano1106 Email , 265 words, 276 views   English (CA)
Categories: C++

shift operator undefined behavior

I was expecting:

int main( int argc, char *argv[] ) 
{ 
   unsigned char m = 32; 
   register unsigned mask = (1<<m); 
   std::cout << std::hex << mask << '\n'; 
   return 0; 
} 

to print 0 but instead this program compiled with g++ (and VC++.NET2003 too) prints 1!

If I change (1<<m) by (1<<32) or if change the program for:

int main( int argc, char *argv[] ) 
{ 
   unsigned char m = 31; 
   register unsigned mask = (1<<m)<<1; 
   std::cout << std::hex << mask << '\n'; 
   return 0; 
} 

it gives me the expected 0.

In the C++ standard document, section 5.8. It is written

"The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand."

The root for this behavior probably originates from C and the safe way to perform a bit shift when the number of bits to shift may exceed the length of the left operand is to implement the shift operation in a function:

Example, almost but not universally portable:

#include <climits> 

unsigned int safe_uint_shift(unsigned int value,
                             unsigned int bits) 
{ 
    if( bits > (CHAR_BIT*std::sizeof(unsigned int) )
    {
      return 0;
    }
    else
    {
        return value << bits; 
    }
}  

Put it in a header and make it inline if you like.

This solution has been proposed by Jack Klein.

The other way that I have used is to promote the left operand to an integer type having enough bits:

register unsigned mask =
  (static_cast<unsigned long long>(1)<<m)<<1;

Comments, Pingbacks:

No Comments/Pingbacks for this post yet...

This post has 1 feedback awaiting moderation...

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.

Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
(Line breaks become <br />)
(Set cookies for name, email and url)
(Allow users to contact you through a message form (your email will NOT be displayed.))

Olivier Langlois's blog

I want you to find in this blog informations about C++ programming that I had a hard time to find in the first place on the web.

February 2012
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

Search

Custom Search

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 2

powered by
b2evolution