在无法访问的代码中停止GCC超出范围的移位警告

时间:2015-12-05 17:28:26

标签: c gcc

假设:

#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;
}

在大小相等的平台上,我得到了这个,有各种版本的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

当类型具有相同的大小时,代码块是不可访问的,因此不会执行坏移位。它只会在long宽于int时执行,在这种情况下,转换不会超出该类型的范围。

我们如何通过这些限制消除这种令人讨厌的警告:

  • 我不想全局禁用它,因为它很有用(当没有误报时)。

  • 我不想分开班次 - 也就是说,将它作为两个连续的左移来执行,这会增加所需的班次。

  • 我不想将if测试转换为预处理器#if。 (对于INT_MAXLONG_MAX,这很容易做到,但在实际程序中很麻烦。)

根据n.m.的回答,我使用了与以下模式非常类似的内容:

const int condition = sizeof (long) > sizeof (int);

if (condition) {
  /*...*/
  x <<= CHAR_BIT * sizeof (int) * condition;
}

在我的实际代码中应用的这种模式会抑制诊断,并且与不乘以condition相比,生成的代码不会发生变化。

2 个答案:

答案 0 :(得分:2)

$('#example').val('only the visual will change')

答案 1 :(得分:0)

我和n.m在同一条路上。但想出了以下看似更符合语义的内容(top sizeof(int)字节来自x)。

x <<= (sizeof(long) - sizeof(int))*CHAR_BIT;