【问题标题】:clang tautological-constant-out-of-range-compare warningclang tautological-constant-out-of-range-compare 警告
【发布时间】:2017-02-20 12:21:10
【问题描述】:

如果我使用 clang 编译以下简单程序 (test.c)

#include <stdio.h>

typedef enum {
    a,
    b
} sample_enum_t;


int main() {
    sample_enum_t sample_enum = -1;
    if (sample_enum == -1) {
        printf("Equals\n");
    }
}

编译器给了我一个警告:

$ clang -o test test.c
test.c:11:21: warning: comparison of constant -1 with expression of type 'sample_enum_t' is always false [-Wtautological-constant-out-of-range-compare]
    if (sample_enum == -1) {
        ~~~~~~~~~~~ ^  ~~
1 warning generated.

如果我执行它在“等于”处打印的程序,比较总是错误的显然不是真的:

$ ./test 
Equals

这是一个clang错误还是我错过了什么?我明白将 -1 分配给 sample_enum 变量不是一个好主意,但它是一个有效的行,并且由于该行,clang 不会给我警告。

我正在使用 clang 3.5.2

【问题讨论】:

  • This Clang issue seems relevant。它没有关闭,所以我不确定它是否已解决。我的理解是他们认为这是一个有用的警告,但应该重新制定它以防止人们根据警告删除代码。
  • 哎呀,那个错误报告已经 3.5 年了。
  • 将分享一个引发此 clang 警告的真实示例:github.com/golems/ach/blob/…

标签: c clang compiler-warnings


【解决方案1】:

暂时先不管Clang是对是错,看看标准是怎么说的吧。

6.7.2.2 Enumeration specifiers:

每个枚举类型都应与 char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,128) 但应能够表示所有枚举成员的值。枚举类型在终止枚举器声明列表的 } 之后是不完整的,然后完成。

128) 实现可能会延迟选择哪种整数类型,直到看到所有枚举常量。

您依赖于实现定义的行为;标准未定义您的实现选择的类型是否可以表示 -1。 Clang 和 GCC 都使用 unsigned int(在我使用 gcc 7.0.1 和 clang 3.8.0 测试您的代码时)。因此,您的代码是有效的,因为代表 -1 没有问题。

所以,这不是一个真正的问题,Clang 的诊断有点用处,因为如果您无意中使用了超出您定义的枚举常量范围的某个值。

【讨论】:

  • "Clang 和 GCC 都使用 unsigned int" 这不是-1 的问题吗?
  • @rootkea 将 -1 分配给 unsigned int 具有明确定义的语义:它将使用约简模数转换为 unsigned int 中可表示的值;相当于分配UINT_MAX。在比较 -1 和 unsigned int 类型时,-1 将以相同的方式转换,例如,-1 == UINT_MAX 将始终为真。因此,将 -1 分配给任何无符号类型都没有问题(除非没有太多实际原因/用途)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多