11

I have following code:

typedef enum
{
    FOO,
    BAR,
    BAZ
} foo_t;

static void afunc(bool is_it_on)
{
    /* Do the job */
}

int main(void)
{
    afunc(BAZ);
    return 0;
}

Compiling this code does not generate any warning message, even with the -Wall -Wextra options given to the compiler. I have even tried with -Wconversion option, which didn't take any effect, because bool and enum seemed to be of same size for g++ (the size of enum type is not defined in specification as far as I know).

I have combed through the GCC manual and found nothing about it.

Questions:

  • Is there a way to force the compiler to generate a warning in cases like this?
  • Or is it that this implicit casting is legal by c++ specification?

Compiler that I am using: GCC 4.1.2 (2007-02-13)


Conclusion:

The only viable solution to this seems to define a new type to represent 0 or 1, and use it instead of bool.

The code would be like following, and g++ complains about type conversion:

typedef enum
{
    FOO1,
    FOO2
} foo_t;

typedef enum
{
    MY_FALSE,
    MY_TRUE
} my_bool_t;

void foo(my_bool_t a)
{
}

int main(void)
{
     /*
      * GCC generates an error.
      * error: cannot convert ‘foo_t’ to ‘my_bool_t’
      * for argument ‘1’ to ‘void foo(my_bool_t)’
      */
    foo(FOO1);
    return 0;
}
5
  • 2
    Because C++’ type system is only good for user-defined types, for built-in types it invariably sucks. Consequence of its C heritage. Commented May 5, 2012 at 18:00
  • Yes it seems so. I've decided to typedef a new type dedicated to represent only 0 or 1, and use it instead of bool which seems to be intended to express true or false. Commented May 5, 2012 at 18:29
  • Have you tried the same with clang? Commented May 10, 2024 at 20:50
  • @JVApen Nope. But I have just tested: Clang all versions available with --std=c++11 -O0 -g -Wall gave me no warning at all, gcc 6 or below with the same compiler option generated no warning either. However, gcc 7.1 or above threw a warning "enum constant in boolean context". BTW, you can test it yourself at godbolt.org :) Commented Aug 7, 2024 at 23:58
  • Compiler-explorer works, unless you are on mobile, in which case you can't type a single letter. I would however recommend using -Weverything when testing if clang has a warning for it. I would expect following to find it: clang.llvm.org/docs/… I'm quite sure I've seen the warning, though I'm used to C++ enums instead of this C-typedeffing Commented Aug 8, 2024 at 4:05

1 Answer 1

9

Yes, those implicit conversions are perfectly legal.

C++11 draft n3290, §4.12 Boolean conversions:

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

Warnings on these conversions (for arithmetic types) would probably lead to huge numbers of warnings all over the place, I don't think it would be manageable.

In C++11, you can use scoped enums to prevent that implicit conversion:

This fails to compile for lack of a conversion from Foo to bool:

enum class Foo { ONE };

void tryit(bool b) { }

int main()
{
    tryit(Foo::ONE);
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you, Mat. If it is legal by C++ specification, I guess the only way to achieve what I want is to typedef a new boolean type just for the project so that the members of the project does not make mistakes such as the code snippet.
Sadly, gcc 4.1.2 does not seem to support 'scoped enums'. I guess I should resort to typedef solution, and it actually works. Normally, you do not need that. But under some circumstances like you are refactoring other people's code, without this 'strict' type checking, you would be sorry. Maybe I should have used lint.
@orchistro: If possible, try to move on to a newer version on gcc (I know it's not easy...). gcc 4.1.x is quite an old branch.
@MatthieuM.: I was frustrated when I found out there was a "company standard compiler" and it was a 'stone age' compiler. I don't even seem to be able to make a dent in the company's policy which is made by a "standard group", lol. Anyway, work is just work :-)
Warnings are not constrained to only behavior which is illegal per the standards. Warnings typically serve to highlight common mistakes or unintentional behavior. Notably, this behavior still exists in GCC8 (no way to get a warning for bool/enum mis-comparison or assignment).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.