Kaz
Kaz

Reputation: 58598

Stop GCC out-of-range shift warning in unreachable code

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:


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

Answers (2)

Anders
Anders

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

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

x <<= (sizeof (long) > sizeof (int) ? CHAR_BIT * sizeof (int) : 0);

Upvotes: 2

Related Questions