Unexpected integer overflow in expression

Viewed 434

I am trying to get an unsigned that will completely be filled with ones (it will be 32 ones in binary representation. I tried to use this:

constexpr unsigned all_ones = (((1 << 31) - 1) << 1) | 1;

but when compiled (g++ on Ubuntu) it gives the following error:

error: overflow in constant expression [-fpermissive]

What is causing this error? To me, the expression looks good, as dismantled here:

1       = 000...001
  << 31 = 100...000
  - 1   = 011...111
  << 1  = 111...110
  | 1   = 111...111

I know that I can get the required value by other means (such as ~0u), but what I'm asking is why doesn't this method work.

2 Answers

Your expression is using signed integer constants and does overflow into the sign bit (which takes you into undefined behavior). You could avoid the error by specifying an unsigned constant:

constexpr unsigned all_ones = (((1U << 31) - 1) << 1) | 1;

But the expression is still overly complicated and is better expressed as:

constexpr unsigned all_ones = ~0U;

I would try to use the defines in the header climits, that's what they are for, you are basically asking for the biggest value that you can represent for an unsigned integer.

constexpr unsigned all_ones = UINT_MAX;

See here: http://www.cplusplus.com/reference/climits/

Related