用于虚假比较的gcc警告标志

用于虚假比较的gcc警告标志,gcc,Gcc,我正在搜索用于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的正确警告标志,以检测以下内容:

#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;
}
发生的事情是,我一直在修改一个现有代码,它使用
unsigned int
作为内存块大小。代码启动失败,文件较大。所以我需要检查我没有遗漏任何剩余的东西

编辑:


刚刚发现<代码> Wtype限制但这对我来说不起作用:

< P> OK,找出窍门,你需要使用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
与:


OK,找出窍门,你需要使用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
与:


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

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

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


只有当程序有限地使用库函数时,开源版本才能很好地工作,但即使如此,它也可以提取g++警告中没有出现的信息。

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

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

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


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

那么您希望它警告什么呢?因为我没有看到任何关于代码的可疑之处,当然n永远不会被修改,因为它的值太大了。但是编译器无法真正看到它。如果它是一个常数size\u t n=-1,那么它可能会告诉你它总是正确的。但除此之外,我看不出它是如何分辨的。顺便说一句,
-Wsign转换
弊大于利。因为它会警告
size\t n=-1
,但这总是意味着
size\t
的最大值,并试图修复它会使事情变得更糟,因为在
size\t n=(size\t)-1
在重构过程中修改错误的风险很小,
大小n=-1u
是完全错误的。那么您希望它警告什么呢?因为我没有看到任何关于代码的可疑之处,当然n永远不会被修改,因为它的值太大了。但是编译器无法真正看到它。如果它是一个常数size\u t n=-1,那么它可能会告诉你它总是正确的。但除此之外,我看不出它是如何分辨的。顺便说一句,
-Wsign转换
弊大于利。因为它警告
size\u t n=-1
,但这总是意味着
size\u t
的最大值并试图修复它会使事情变得更糟,因为在
size\u t n=(size\u t)-1
中,重构过程中修改错误的风险很小,
size\u n=-1u
是完全错误的,gcc-4.7.1和clang-3.1检测到此处的条件始终为真(通过优化)。测试将在生成的部件中删除。他们只是不警告而已。@Danielfer觉得很有趣。。。这涉及到对未定义行为的讨论,以及编译器如何悄悄地利用这些行为而不是警告它们(尽管这里没有未定义的内容)。嗯,当我用
替换for循环时,while(1)
,clang警告
始终为true。c:12:10:warning:将永远不会执行[-Wunreachable code]
。那么,如果我使“始终真实”条件变得不那么明显,为什么它不发出警告,但它仍然检测到它始终真实?gcc-4.7.1和clang-3.1都检测到该条件始终真实(经过优化)。测试将在生成的部件中删除。他们只是不警告而已。@Danielfer觉得很有趣。。。这涉及到对未定义行为的讨论,以及编译器如何悄悄地利用这些行为而不是警告它们(尽管这里没有未定义的内容)。嗯,当我用
替换for循环时,while(1)
,clang警告
始终为true。c:12:10:warning:将永远不会执行[-Wunreachable code]
。那么,如果我使“始终为真”条件不那么明显,但它仍然检测到它始终为真,为什么它不发出警告呢?
$ 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.