11

Is there any gcc flag to forbid implicit bool to int conversion?

I want to get any warning with this code:

void function( int value, bool flag ) { }

int main()
{
  int a = 123;
  bool flag = true;

  //oops, a common mistake
  function( flag, a );
}
Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
yarrr
  • 163
  • 1
  • 6
  • 1
    To use `bool` in C you need to `#include ` – pmg Feb 25 '15 at 10:29
  • An implicit conversion is not a "cast". A cast, by definition, must be an explicit conversion. Also, are you asking about C or C++? They're different languages. – The Paramagnetic Croissant Feb 25 '15 at 10:42
  • As to the error: your "common mistake" is easily detected by the fact that it also performs a **narrowing** conversion from `int` to `bool`. You can warn on that instead. – The Paramagnetic Croissant Feb 25 '15 at 10:43
  • Removed the c tag, since this question doesn't appear to be about C. If that's wrong, please do add it back, but then remove the c++ tag. –  Feb 25 '15 at 11:28

6 Answers6

6

As a workaround, in C++11, you may delete the other possible overloads:

template <typename T> void function(int, T) = delete;
Jarod42
  • 203,559
  • 14
  • 181
  • 302
5

To answer your question: no, there is no gcc flag to issue a warning in that case. Your problem was discussed several times on the gcc mailing list. For example here:

The main reason why this is not checked by the compiler lies in the fact that otherwise each statement like if( intval ) would raise a warning too.

user0815
  • 1,376
  • 7
  • 8
  • Summarizing: "Apparently, we disagree. As I don't see a need to change the compiler, I won't do it myself. If you feel strongly that such a change is needed, please send a patch to gcc-patches@gcc.gnu.org, changing the compiler accordingly. Regards, Martin" – amordo Dec 03 '22 at 10:03
2

Use a wrapper class:

class Boolean
{
    bool flag;
public:
    explicit Boolean(bool something){}

    bool getValue() const {return flag;}
    void setValue(bool a) {flag = a;}
};

void function(int value,Boolean flag ) { }

int main()
{
  int a = 123;
  Boolean flag(true);

  function( flag, a ); // fails! Boolean isn't a int value :)
}
Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
amchacon
  • 1,891
  • 1
  • 18
  • 29
2

In C, you can wrap a value in a generic-selection that only supports one type:

#include <stdbool.h>
#include <stdio.h>

bool x = true;
int y = _Generic(1, bool:2);

int main(void) {
    printf("%d\n", y);
}

This errors out (GCC 4.9), but will compile without complaint if you replace the 1 with true or x.

So for your example:

#include <stdbool.h>

void function( int value, bool flag ) { }
#define function(V, F) function(V, _Generic(F, bool:F))

int main() {
  int a = 123;
  bool flag = true;

  function( flag, a );  // error: '_Generic' selector of type 'int' is not compatible with any association
}
Alex Celeste
  • 12,824
  • 10
  • 46
  • 89
2

clang-tidy will warn you, or even better, make this an error for you.

The test for this is readability-implicit-bool-conversion. In earlier versions of the linter the test is named readability-implicit-bool-cast.

Mathias
  • 1,446
  • 2
  • 16
  • 31
0

Using the idea in the question min macro in kernel.h you can use gcc's typeof

#include <stdbool.h>

#define function(x, y) do {                             \
                           __typeof(x) tmpone = (x);    \
                           int tmptwo = 0;              \
                           (void) (&tmpone == &tmptwo); \
                           fx((x), (y));                \
                       } while (0)

void fx(int value, bool flag) {
    (void)value;
    (void)flag;
}

int main(void) {
    int a = 123;
    bool flag = true;

    function(a, flag);
    function(flag, a); // oops, a common mistake
}
Community
  • 1
  • 1
pmg
  • 106,608
  • 13
  • 126
  • 198