1

给定:

定义为的类型TheValueT可以任意配置,例如uint8_tint64_。让有一些代码:

TheValueT   x = ...;

... do something to 'x' ...

if( x < 0 ) {
   /* Do something. */
}

问题:

碰巧如果TheValueT定义为无符号类型,编译器会抱怨“由于类型范围有限,条件始终为真......”。

问题:

如何在让TheValueT仍然是任意整数类型的同时避免编译器警告?该解决方案应适用于最广泛的 C 编译器。

4

3 回答 3

2

编写测试的一种简单而安全的方法是:

TheValueT x = /* ... */;

if (x < 1 && x != 0) {
    // do something
}

无论如何,一个足够聪明的编译器可能会对此发出警告,但是对于可以编写以涵盖所有可能的整数类型(包括扩展类型)的任何正确替代方案也是如此。这确实解决了我实施中的警告。

没有任何替代方法需要涉及定义的值的算术计算x在所有情况下都会产生正确的结果——这些会遇到值x在其或其他类型范围的极端值的问题。

这确实假设TheTypeT必须是整数类型。如果浮动类型也是可能的,那么您最好的选择可能是忍受警告,或者使用编译器标志在生产构建期间关闭该特定警告。

于 2019-06-06T13:17:19.447 回答
1

一个主题的变奏。也适用于 FP。

if (x <= 0 && x != 0) {
于 2019-06-07T03:02:23.090 回答
1

也许是通用解决方案?

#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
于 2019-06-06T13:00:01.170 回答