質問

Is there any way to have gcc or g++ emit a warning when an implicit conversion within an if, something like if(25.0), is used?

This question is inspired by a bug I recently observed where a parenthesis was mis-placed, and the if statement has the unexpected behavior illustrated in the example below. I understand from this discussion on the comma operator that this is valid (although ugly) code, but I would like to get a warning. I tried -Wconversion -Wall -pedantic with g++ (GCC) 4.1.2 and g++ (GCC) 4.6.3 without any luck.

#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");
}

This produces:

 pass (p( ), )
 fail (p( , ))
役に立ちましたか?

解決

In C and C++ all expressions are essentially evaluated down to a logical expression: true or false? true is any non-zero value while false is zero.

What's happening is that your expression

if(passMin(val), minval)

is falling foul of the , operator, which evaluates the expression on the left side and discards the result, then proceeds to evaluate the expression on the right and return that value.

The comma operator has the lowest precedence of any operator and is left associative.

Essentially, the code above means

void(passMin(val));
if (minVal)

It's very unlikely that any current compiler provides an option to restrict this pattern, because it is very widely used for things like pointer and zero checks:

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

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

So if you did have an option you would probably cripple most libraries, STL, boost, etc.

That said, you could probably use a static analyzer to enforce a code practice that prohibits it within your own code.

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

Clang static analyzer: http://clang-analyzer.llvm.org/ (the page is not all that helpful, the analyzer seems to come with 3.5 so additional searches will be required to find better documentation)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top