让gcc在if语句中的类型转换发出警告

3
有没有办法让 gccg++if 语句中发生隐式转换时(比如: if(25.0)) 发出警告?
这个问题的灵感来自我最近观察到的一个 bug,其中括号位置错了,if 语句的行为与下面的示例所示的预期行为不同。从逗号运算符的这次讨论中我明白这是有效的(虽然丑陋),但我想得到一个警告。 我尝试了使用 g++ (GCC) 4.1.2g++ (GCC) 4.6.3 的选项 -Wconversion -Wall -pedantic,但都没有成功。
#include <cstdio>

bool passMin(float val, float minval=10.) {return minval<val;}

int main () {
  float val(20.0), minval(25.0);
  if(passMin(val), minval) printf(" pass (p( ), )"); else printf(" fail (p( ), )");
  printf("\n");
  if(passMin(val, minval)) printf(" pass (p( , ))"); else printf(" fail (p( , ))");
  printf("\n");
}

这将产生如下结果:
 pass (p( ), )
 fail (p( , ))

不确定这是容易实现的,因为可能存在使用此方法实现某些目的的情况。不使用默认值是个好主意... ;) - Mats Petersson
你可以自定义GCC,例如使用MELT或者用C编写一个插件来实现你的目标。然而,我也认为相当多的代码在非布尔值上使用if语句... - Basile Starynkevitch
1
如果您使用clang,它会为此提供一个不错的警告,可以在此链接中查看。因此,如果可以使用clang,那么您可能很幸运。 - Shafik Yaghmour
@ShafikYaghmour 我还没有太多时间玩clang,但它看起来非常有前途。谢谢! - user2148414
1
在这种特定情况下,GCC警告-Wfloat-equal可以覆盖它。该警告是关于精确比较的,其中一个操作数是浮点类型。在if语句中使用浮点值执行与零的精确比较。 - user743382
显示剩余2条评论
1个回答

1
在 C 和 C++ 中,所有表达式本质上都会被转化为一个逻辑表达式:真或假?真是任何非零值,而假是零。

发生的情况是,你的表达式

if(passMin(val), minval)

代码中的 , 运算符出现了问题,它会先计算左侧表达式并丢弃结果,然后再计算右侧表达式并返回其值。
逗号运算符是所有运算符中优先级最低的,并且是从左往右结合的。
简而言之,上述代码意味着:
void(passMin(val));
if (minVal)

目前很少有编译器提供限制此模式的选项,因为它被广泛用于指针和零检查等操作。

for (Node* node = list->head; node; node = node->next)
    ...

void func(const char* str) {
    assert(str);
    ...

如果您有选择的话,您可能会破坏大多数库、STL、boost等。但是,您可以使用静态分析器来强制执行禁止在自己的代码中使用它的编码实践。

Visual Studio: http://msdn.microsoft.com/en-us/library/dd380660.aspx

Clang静态分析器: http://clang-analyzer.llvm.org/ (该页面并不是很有帮助,分析器似乎随着3.5一起提供,因此需要进行其他搜索以找到更好的文档)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接