由于数据类型范围有限,警告抑制“比较总是假的”选项

时间:2014-11-20 12:55:52

标签: c gcc gcc-warning

给出一些代码:

unsigned short val;
//<some unimportant code that sets val>

if(val>65535) val=65535;

我们怎样才能禁用“由于数据类型范围有限,比较总是假的”来自gcc的警告?

这是使用GCC 4.1.2,因此没有#pragma GCC diagnostics构造。 我找不到-W选项来关闭它。

我试过做一个val的演员:

if(((long)val)>65535); val=65535

但似乎GCC足够聪明,仍能发出警告。

编译器标志是-Wall,就是这样。没有-Wextra。

我真的不想删除检查 - 此目标上的短路可能是16位,但并不意味着它必须是。我很高兴以不同的方式写支票。

我想打开-Werror,所以这个警告必须要去。

编辑1 不重要的代码并不那么重要:

unsigned short val;
float dbValue; (actually function parameter)
val= ((unsigned short) dbValue) & 0xffff);
if(val>65535) val=65535;

因此,如果短的大小发生变化,我们就会溢出,无论如何,范围检查都变得毫无意义,可以删除,或者更多地应用于浮点值。

编辑2 虽然到目前为止的答案有助于改进代码,但知道在gcc 4.1.2中是否有任何方法可以禁用此警告仍然是有用的 - 这就是问题所在。

似乎可以使用-Wno-type-limits

在最近的版本中完成

4 个答案:

答案 0 :(得分:3)

从理论上讲,你的问题没有答案:如果你打算写的是关于val的所有可能值的无操作(针对特定的架构),那么代码可以达到,那么编译器可以警告它对所有人来说都是无操作...

在实践中,比较(val + 0)而不是val可能足以让编译器生成与原始版本相同的代码,同时关闭它。

我建议你写

#include <limits.h>
…
#if USHRT_MAX > 65535
if(val>65535) val=65535;
#endif

我觉得如果你在没有评论的情况下使用它,它会使意图比任何令人费解的技巧更清晰。

答案 1 :(得分:2)

您可以使用条件编译:

#include <limits.h>

unsigned short val;

#if USHRT_MAX > 65535
  if(val>65535) val=65535;
#endif

答案 2 :(得分:0)

val被声明为unsigned short通常(请参阅注释)表示16位无符号(0 - 65535),因此您的测试永远不会成为现实,因为使用此编译器val永远不会超过2 ^ 16-1(65535),并且使用此目标架构

将其投放为long不会改变任何内容。您可能希望将val声明为unsigned long

修改

note :正如评论部分所暗示的那样,shortint类型的确切宽度取决于编译器和目标体系结构。维基百科有一个关于basic C data types的部分,更详细地介绍了这个问题。

答案 3 :(得分:0)

使用min宏:

#define min(x, y)   (((x) < (y)) ? (x) : (y))
val=min(val,65535);

摆脱了警告。所以我们也可以直接使用相同的实现

val=(val)<(65535)? val: 65535;

这里的技巧是,虽然16位整数不能大于65535,但它可以是65535,并且此版本中的检查是“它是否低于65535