2

Is there a way to make clang (or gcc) warn you if you use integer constants with boolean operators? Specifically (but not only) in an if context?

What I mean is, I wrote:

enum MatchType {MATCHED, FAKE, DUMMY};

if (matchType == MatchType::FAKE || MatchType::DUMMY) {
    // ...
}

where it should have been

if (matchType == MatchType::FAKE || matchType == MatchType::DUMMY) {

The OR operation with a constant clearly doesn't make sense (especially when it is not a literal 0 or 1). Any idea how to prevent this? (I know using switch would be the right thing to do in this specific case, and would prevent this kind of mistake, but I'm still interested in an answer.)

The similar question "is there a gcc warning for conditional expression is constant" is focused on the case where you have an expression in an if that - after simplification - is constant. I'm asking about the case where you use boolean operators on non-bool constants, for example:

bool result = flags && 42;  // you might have meant `&`

Also, in this case the conditional expression is not constant (depends on a), but it is probably still a mistake:

if (a == 5 && 6) { /*...*/ }
Community
  • 1
  • 1
jdm
  • 9,470
  • 12
  • 58
  • 110
  • 2
    http://stackoverflow.com/questions/22852364/is-there-a-gcc-warning-for-conditional-expression-is-constant – M.M Nov 28 '15 at 12:10
  • The other question overlaps my question, and actually addresses my *concrete* problem. But the question *as asked* is different... I'm asking about using `||` and `&&` on non-bools. You can have cases where "the conditional expression is *not* constant", or you are not using `if` at all, and I'd still like a warning. – jdm Nov 28 '15 at 13:54
  • By "constants", you mean `constexpr` (compile-time constant), not `const` (dynamic initialization but immutable thereafter), correct? – Ben Voigt Nov 28 '15 at 16:43
  • @BenVoigt Neither specifically. I mean mostly literals, but also enum values, yes also `constexpr`, and whatever the compiler happens to deduce at compile time. – jdm Nov 28 '15 at 18:49
  • 1
    If the compiler doesn't help you, you have to do the check yourself at compile time. In case of enums, a wrapper class can do the trick, something like this: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum – Karoly Horvath Nov 28 '15 at 19:13
  • For the record, both GCC 10 and Clang 10 warn about this with `-Wall`. – HolyBlackCat Jun 23 '20 at 12:48

1 Answers1

0

Recent version of gcc and clang provides Wint-in-bool-context warning which checks exactly this.

Alternatively, if you're using C+11, you can use enum class

enum class MatchType {MATCHED, FAKE, DUMMY};

(I'm assuming your compiler supports C++11, since you're using MatchType::FAKE to reference the enum instead of FAKE)

enum class provides better type safety than plain enum. See Why is enum class preferred over plain enum?

Arnaud
  • 536
  • 5
  • 13