假设我有以下功能:
#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的无意义比较。当然这是真的,它使得感。
但是,假设我做希望对零的检查出于一个或多个可能的原因,例如:
是否有一种体面,合理的便携方式可以在不完全关闭警告的情况下使警告静音?
依赖于'STATIC_ASSERT()'的功能(我可以使用)可以接受,如果合理的话。如果类型更改以强制某人查看代码,我可以打破编译。但重要的是要注意typeof
不是我在我所针对的所有编译器中都可用的。
我特意寻找C语言解决方案,因此模板在这里没有任何用处......
答案 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_BOUND
和LOWER_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?您可以通过重载来处理特定情况,并避免屏蔽警告,更明确地声明您正在处理您正在处理的案例。根据我的经验,这往往会迫使您测试新代码,而不是掩盖将来可能发生的事情(比如突然改变数据类型,然后不得不处理神秘地未达到预期范围的值)。