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
iftest into a preprocessor#if. (This is easy to do in this case withINT_MAXandLONG_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.