【问题标题】:Why does gcc not warn when an enum or int value is passed on as a function's argument which is bool?为什么当枚举或 int 值作为 bool 函数的参数传递时 gcc 不发出警告?
【发布时间】:2012-05-05 17:32:55
【问题描述】:

我有以下代码:

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 选项,但没有效果,因为boolenum 似乎对于g++ 具有相同的大小。 (据我所知,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;
}

【问题讨论】:

  • 因为 C++ 的类型系统只适用于用户定义的类型,而对于内置类型,它总是很糟糕。其 C 遗产的后果。
  • 是的,看起来是这样。我决定 typedef 一个新类型,专用于仅表示 0 或 1,并使用它来代替 bool,这似乎是为了表示 truefalse。跨度>

标签: c++ gcc g++ gcc-warning


【解决方案1】:

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

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

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

这些转换的警告(对于算术类型)可能会导致大量警告遍布各处,我认为这将是难以管理的。

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

由于缺少从Foobool 的转换,编译失败:

enum class Foo { ONE };

void tryit(bool b) { }

int main()
{
    tryit(Foo::ONE);
}

【讨论】:

  • 谢谢你,马特。如果它在 C++ 规范中是合法的,我想实现我想要的唯一方法是为项目 typedef 一个新的 boolean 类型,这样项目的成员就不会犯代码 sn-p 之类的错误。跨度>
  • 遗憾的是,gcc 4.1.2 似乎不支持“范围枚举”。我想我应该求助于 typedef 解决方案,它确实有效。通常,您不需要它。但是在某些情况下,比如你正在重构其他人的代码,如果没有这种“严格”的类型检查,你会很抱歉。也许我应该使用 lint。
  • @orchistro:如果可能,请尝试在 gcc 上使用更新的版本(我知道这并不容易......)。 gcc 4.1.x 是一个相当古老的分支。
  • @MatthieuM。我非常愿意这样做。我是最后一个不欢迎编译器升级的人。但公司不允许。
  • @orchistro:我猜这可能是问题所在,我很生气,因为我在工作中被困在 4.3 分支,所以我当然可以同情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多