【问题标题】:gcc warning flag for bogus comparison用于虚假比较的 gcc 警告标志
【发布时间】:2013-03-01 15:02:32
【问题描述】:

我正在寻找与 gcc 一起使用的正确警告标志,以检测以下内容:

#include <stdlib.h>
#include <stdio.h>
int main()
{
  const size_t n = (size_t)-1;
  for( unsigned int i = 0; i < n; ++i ) /* use `unsigned char` if you want */
    {
    printf( "%d\n", i );
    }
  return 0;
}

我试过了:

$ gcc -Wsign-conversion -Wconversion -pedantic -Wsign-compare -W -Wall -Wextra -std=c99  t.c 

发生的事情是我一直在修改现有代码,该代码使用unsigned int 作为内存块大小。代码以较大的文件开始失败。所以我需要检查我没有遗漏任何剩余的东西。

编辑:

刚刚发现-Wtype-limits,但这又不适合我

【问题讨论】:

  • 那么你希望它警告什么?因为我没有看到任何关于代码的可疑之处,当然 n 永远不会因为它的值太大而被修改。但是编译器看不到它。如果它是一个 const size_t n = -1,那么它可能会告诉你它总是正确的。但除此之外,我看不出它是如何分辨的。
  • 顺便说一句,-Wsign-conversion 弊大于利。因为它会警告size_t n = -1,但这始终意味着size_t 的最大值并试图修复它会使事情变得更糟,因为在size_t n = (size_t)-1 中,在重构期间修改它的风险很小,而size_t n = -1u 是完全错误的.

标签: gcc


【解决方案1】:

您要求编译器在运行时检测条件始终为真。在这种情况下,这几乎没有可能,因为它总是正确的原因是一侧是恒定的,而另一侧受 unsigned int 类型的限制。我很高兴你找到了一个 g++ 标志,但是如果变量 n 的值是在不同的文件中提供的,或者没有键入为 const,例如,编译器可能无法检测到该条件保持真实。

您也可以考虑使用静态分析器,它比编译器花费更多时间来检测运行时可能发生和可能不会发生的事情。一种开源 C 分析器是Frama-C

在屏幕截图中,红色的语句已被检测为无法访问。

开源版本只有在程序有限使用库函数的情况下才能正常工作,但即便如此,它也可以提取 g++ 警告中没有出现的信息。

【讨论】:

  • gcc-4.7.1 和 clang-3.1 都检测到条件在此处始终为真(经过优化)。测试在生成的程序集中被删除。他们只是不警告。
  • @DanielFischer 有趣...这与关于未定义行为以及编译器如何静默利用它们而不是警告它们的讨论有关(尽管这里没有未定义的内容)。 blog.llvm.org/2011/05/…
  • 嗯,当我用 while(1) 替换 for 循环时,clang 警告 always_true.c:12:10: warning: will never be executed [-Wunreachable-code]。那么,如果我让永远为真的条件不那么明显,为什么它不发出警告,但它仍然检测到它永远为真?
【解决方案2】:

好的,找到窍门了,你需要改用c++编译器:

$ g++ -Wextra  t.c
t.c: In function ‘int main()’:
t.c:6: warning: comparison is always true due to limited range of data type

与:

$ g++ --version
g++ (Debian 4.4.5-8) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【讨论】:

    猜你喜欢
    • 2023-04-08
    • 1970-01-01
    • 2023-03-29
    • 2012-04-17
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    相关资源
    最近更新 更多