Reputation: 58598
Given:
#include <stdio.h>
#include <limits.h>
int main()
{
if (sizeof (long) > sizeof (int)) {
long x = 42;
x <<= CHAR_BIT * sizeof (int);
}
printf("sizeof (long) == %d\n", (int) sizeof (long));
printf("sizeof (int) == %d\n", (int) sizeof (int));
return 0;
}
On a platform where the sizes are equal I get this, with various version of GCC:
$ gcc -Wall shiftcomplain.c -o shiftcomplain
shiftcomplain.c: In function ‘main’:
shiftcomplain.c:8:5: warning: left shift count >= width of type [enabled by default]
$ ./shiftcomplain
sizeof (long) == 4
sizeof (int) == 4
The code block is not reachable when the types have an equal size, so the bad shift will never execute. It will only execute if long
is wider than int
, in which case the shift will not be out of range for that type.
How can we eliminate this annoying warning, with these constraints:
I don't want to disable it globally because it is useful (when not falsely positive).
I don't want split the shift---that is, perform it as two consecutive left shifts which add to the desired shift size.
I don't want to convert the if
test into a preprocessor #if
. (This is easy to do in this case with INT_MAX
and LONG_MAX
, but troublesome in the actual program.)
Based on n.m.
's answer, I'm using something very similar to the following pattern:
const int condition = sizeof (long) > sizeof (int);
if (condition) {
/*...*/
x <<= CHAR_BIT * sizeof (int) * condition;
}
This pattern applied in my actual code suppresses the diagnostic, and the generated code doesn't change compared to not multiplying by condition
.
Upvotes: 0
Views: 181
Reputation: 2316
I was on the same path as n.m. but came up with the following which seems more semantically what might have been intended (the top sizeof(int) bytes are from x).
x <<= (sizeof(long) - sizeof(int))*CHAR_BIT;
Upvotes: 0
Reputation: 119877
x <<= (sizeof (long) > sizeof (int) ? CHAR_BIT * sizeof (int) : 0);
Upvotes: 2