如何使一个特定的“无符号与零无意义的比较”警告沉默?

时间:2011-06-06 23:37:39

标签: c warnings

假设我有以下功能:

#define LOWER_BOUND 0
#define UPPER_BOUND 42

int is_value_in_range( some_typedef val)
{
    return ((LOWER_BOUND <= val) && (val <= UPPER_BOUND));
}

假设我已正确配置警告,如果some_typedef原来是无符号类型,我会收到警告,指出无符号类型与0的无意义比较。当然这是真的,它使得感。

但是,假设我希望对零的检查出于一个或多个可能的原因,例如:

  • 虽然边界始终是编译时常量,但它们可能会发生变化(并且宏可能不会“非常”接近函数)。例如,可以通过将选项传递给编译器来设置边界。
  • 我可能希望防止以后将typedef更改为signed类型,因为在更改时可能不会仔细检查typedef的每次使用。

是否有一种体面,合理的便携方式可以在不完全关闭警告的情况下使警告静音?

依赖于'STATIC_ASSERT()'的功能(我可以使用)可以接受,如果合理的话。如果类型更改以强制某人查看代码,我可以打破编译。但重要的是要注意typeof不是我在我所针对的所有编译器中都可用的。

我特意寻找C语言解决方案,因此模板在这里没有任何用处......

4 个答案:

答案 0 :(得分:6)

如果不知道some_typedef未签名或签名,我认为你很不走运。

如果您事先知道some_typedef是未签名的,则可以使用

#if LOWER_BOUND > 0
    return ((LOWER_BOUND <= val) && (val <= UPPER_BOUND));
#else
    return ((val <= UPPER_BOUND));
#endif

或者在这种情况下,您可以使用我的首选版本:

    return (val-LOWER_BOUND <= UPPER_BOUND-LOWER_BOUND);

修改:如果不知道some_typedef是否具有特定签名,我将假设UPPER_BOUNDLOWER_BOUND都必须为正。否则,some_typedef被提升为无符号将导致非常古怪的结果。因此,您可以随时安全地使用:

    return ((uintmax_t)val-LOWER_BOUND <= UPPER_BOUND-LOWER_BOUND);

答案 1 :(得分:2)

这通常由pragma控制。对于MSVC,您有#pragma warning,对于GCC,您有diagnostic pragmas(当然不允许对MSVC的警告进行细粒度控制,但这就是你所拥有的。)

两者都允许推/弹机制只改变几行代码的警告。

答案 2 :(得分:1)

我提出了一个非常简单直接的解决方案。将下限复制到变量会导致编译器停止抱怨:

#define LOWER_BOUND 0
#define UPPER_BOUND 42

int is_value_in_range( some_typedef val)
{
    some_typedef lowerbound = LOWER_BOUND;

    return ((lowerbound <= val) && (val <= UPPER_BOUND));
}

我希望在优化的构建中,编译器仍然可以轻松摆脱不变的比较(我必须验证)。

答案 3 :(得分:0)

为什么不对它做一些事情并首先避免使用typedef?您可以通过重载来处理特定情况,并避免屏蔽警告,更明确地声明您正在处理您正在处理的案例。根据我的经验,这往往会迫使您测试新代码,而不是掩盖将来可能发生的事情(比如突然改变数据类型,然后不得不处理神秘地未达到预期范围的值)。