I am trying to set the most significant bit in a long long unsigned, x. To do that I am using this line of code:
x |= 1<<((sizeof(x)*8)-1);
I thought this should work, because sizeof gives size in bytes, so I multiplied by 8 and subtract one to set the final bit. Whenever I do that, the compiler has this warning: "warning: left shift count >= width of type"
I don't understand why this error is occurring.
1 that you are shifting is a constant of type
int, which means that you are shifting an
int value by
sizeof(unsigned long long) * 8) - 1 bits. This shift can easily be more than the width of
int, which is apparently what happened in your case.
If you want to obtain some bit-mask mask of
unsigned long long type, you should start with an initial bit-mask of
unsigned long long type, not of
1ull << (sizeof(x) * CHAR_BIT) - 1
An arguably better way to build the same mask would be
~(-1ull >> 1)
~(~0ull >> 1)
use 1ULL << instead of 1 <<
Using just "1" makes you shift an integer. 1ULL will be an unsigned long long which is what you need.
An integer will probably be 32 bits and
long long probably 64 bits wide. So shifting:
1 << ((sizeof(long long)*8)-1)
will be (most probably):
1 << 63
Since 1 is an integer which is (most probably) 32 bits you get a warning because you are trying to shift past the MSB of a 32 bit value.
1 you are shifting is not automatically an
unsigned long long (but an
int) and thus does not have as many bits as you need. Suffix it with
1ULL), or cast it to
unsigned long long before shifting to make it the correct type.
Also, to be a bit safer for strange platforms, replace
CHAR_BIT. Note that this is still not necessarily the best way to set the most significant bit, see, e.g., this question for alternatives.
You should also consider using a type such as
uint64_t if you're assuming
unsigned long long to be a certain width, or
uint_least64_t if you need at least a certain width, or
uintmax_t if you need the largest available type.