当使用if
中的隐式转换(如if(25.0)
)时,是否有任何方法可以让gcc
或g++
发出警告?
这个问题的灵感来自我最近观察到的一个错误,其中括号放置错误,if
语句具有以下示例中所示的意外行为。我从这次关于逗号运算符的讨论中了解到,这是有效的(尽管很难看)代码,但我想得到一个警告。我尝试了-Wconversion -Wall -pedantic
与g++ (GCC) 4.1.2
和g++ (GCC) 4.6.3
,但没有任何运气。
#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( , ))
在C和C++中,所有表达式的求值本质上都是逻辑表达式:true还是false?true是任何非零值,而false是零。
发生的事情是你的表情
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,因此需要额外的搜索才能找到更好的文档)