10

我有以下代码:

typedef enum
{
    FOO,
    BAR,
    BAZ
} foo_t;

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

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

编译此代码不会生成任何警告消息,即使-Wall -Wextra为编译器提供了选项。我什至尝试过使用-Wconversion选项,但没有效果,因为g++boolenum大小似乎相同。enum(据我所知,规范中没有定义类型的大小)

我梳理了 gcc 手册,并没有发现任何关于它的信息。

问题:

  • 在这种情况下,有没有办法强制编译器生成警告?
  • 还是这种隐式转换在 c++ 规范中是合法的?

我正在使用的编译器:gcc 4.1.2


已编辑

结论:

唯一可行的解​​决方案似乎是定义一个新类型来表示 0 或 1,并使用它来代替bool.

代码如下所示,并且 g++ 抱怨类型转换:

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;
}
4

1 回答 1

9

是的,那些隐式转换是完全合法的。

C++11 草案 n3290,§4.12布尔转换

算术、无范围枚举、指针或指向成员类型的指针的纯右值可以转换为 bool 类型的纯右值。将零值、空指针值或空成员指针值转换为 false;任何其他值都将转换为 true。std::nullptr_t 类型的纯右值可以转换为 bool 类型的纯右值;结果值为假。

这些转换的警告(对于算术类型)可能会导致大量警告遍布整个地方,我认为它是不可管理的。

在 C++11 中,您可以使用作用域枚举来防止隐式转换:

Foo由于缺少从to的转换,这无法编译bool

enum class Foo { ONE };

void tryit(bool b) { }

int main()
{
    tryit(Foo::ONE);
}
于 2012-05-05T17:42:59.307 回答