c++ - 关于 const 禁止的重言式比较的警告?

标签 c++ gcc warnings clang

以下代码在 GCC 和 Clang 上生成警告:

int main() {
  unsigned n = 0;
  return ( n < 0 ) ? 1 : 0;
}

警告是:

$ g++-4.7 -std=c++11 -O3 -Wall -Wextra t.cc -o t
t.cc: In function ‘int main()’:
t.cc:3:16: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
$ clang++-3.2 -std=c++11 -O3 -Wall -Wextra t.cc -o t
t.cc:3:14: warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
  return ( n < 0 ) ? 1 : 0;
           ~ ^ ~
1 warning generated.
$ 

到目前为止,还不错。现在我将变量更改为 const :

int main() {
  const unsigned n = 0;
  return ( n < 0 ) ? 1 : 0;
}

而且两个编译器突然很乐意在没有警告的情况下编译代码:

$ g++-4.7 -std=c++11 -O3 -Wall -Wextra t.cc -o t
$ clang++-3.2 -std=c++11 -O3 -Wall -Wextra t.cc -o t
$ 

问题:为什么会发生这种情况?是否有原因,为什么 const 变量会抑制警告?如果 GCC 和 Clang 都同意,我会犹豫是否向他们提交错误报告,因为我似乎更有可能需要学习一些东西:)

编辑:编译器的常量折叠可能与它有关,但不足以解释这种行为。在第一个示例中(没有 const ),编译器确实知道该值并且它永远不会改变。我检查了汇编器输出,编译器确实进行了常量折叠,但它仍然生成警告,可能之前它在看到表达式 ( n < 0 ) 时用已知常量替换变量并且知道 n 是无符号类型。那就是说:为什么当我添加 const 时这种行为会改变?我认为如果第一个示例产生警告,那么第二个示例也应该可以产生警告。

最佳答案

这是一个明确的常量——您的意图。您想要的警告有效地转移自:

warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
return ( n < 0 ) ? 1 : 0;
         ~ ^ ~

-Wunreachable-codeconst:

warning: will never be executed [-Wunreachable-code]
return ( n < 0 ) ? 1 : 0;
                   ^

注意:-Wtautological-compare 编译器可能仍会在值未知时发出警告。

关于c++ - 关于 const 禁止的重言式比较的警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15173219/

相关文章:

c++ - 作为类私有(private)成员的无名结构/union

c++ - 包含 C 文件/与 CMake 的链接不适用于 C++ : cannot include function

c++ - decltype的非终止递归使用

c++ - 如何查看 boost set<cpp_int> 中的下一个和上一个元素

c - 静态与动态链接

c - C中的String Inverter Program中的警告

c++ - 在 C++ 中链接非重叠、非连续的迭代器 (/boost)

c++ - 如何在 Linux 上读取目录中的文件?

c++ - G++ 4.8.2 坚持简单变量成员是数组

r - data.table fifelse 给出错误警告?