给定:
定义为可以任意配置的TheValueT
的类型,例如uint8_t
或int64_
。让我们有一些代码:
TheValueT x = ...;
... do something to 'x' ...
if( x < 0 ) {
/* Do something. */
}
问题:
碰巧的是,如果TheValueT
被定义为无符号类型,编译器会抱怨"条件总是为真,因为类型范围有限......"。
问题:
如何避免编译器警告,同时让TheValueT
仍然是任意整数类型?该解决方案应适用于最广泛的 C 编译器。
编写测试的一种简单而安全的方法是:
TheValueT x = /* ... */;
if (x < 1 && x != 0) {
// do something
}
无论如何,足够聪明的编译器可能会警告这一点,但是对于可以编写以涵盖所有可能的整数类型(包括扩展类型(的任何正确替代方法也是如此。 这确实可以解决我的实现中的警告。
没有其他需要涉及定义值的算术计算的替代方案x
在所有情况下都能产生正确的结果 - 这些都会遇到x
值在其或其他类型范围的极端值的问题。
这确实假定TheTypeT
必须是整数类型。 如果浮动类型也是可能的,那么最好的办法可能是只接受警告,或者使用编译器标志在生产构建期间关闭该特定警告。
也许是一个通用解决方案?
#include <stdio.h>
#include <stdlib.h>
#define less_than_zero(x) _Generic((x) + 0,
int: (x) < 0,
long: (x) < 0,
long long: (x) < 0,
default: (x) * 0
)
#if 1
int main(void) {
short sh = -1;
int i = -1;
long long ll = -1;
unsigned short us = -1u;
unsigned u = -1u;
unsigned long long ull = -1u;
if (less_than_zero(sh)) puts("sh");
if (less_than_zero(i)) puts("i");
if (less_than_zero(ll)) puts("ll");
if (less_than_zero(us)) puts("us");
if (less_than_zero(u)) puts("u");
if (less_than_zero(ull)) puts("ull");
return 0;
}
由于类型警告的范围有限,没有条件始终为真。
输出
sh
i
ll
主题的变体。也适用于FP。
if (x <= 0 && x != 0) {