C++ 为什么gcc在枚举或int值作为函数传递时不发出警告';谁的论点是布尔?
我有以下代码:C++ 为什么gcc在枚举或int值作为函数传递时不发出警告';谁的论点是布尔?,c++,gcc,g++,gcc-warning,C++,Gcc,G++,Gcc Warning,我有以下代码: typedef枚举 { 福, 酒吧, 巴兹 }富特; 静态无效afunc(布尔值为开) { /*做好这项工作*/ } 内部主(空) { afunc(BAZ); 返回0; } 编译此代码不会生成任何警告消息,即使给编译器提供了-Wall-Wextra选项。我甚至尝试过使用-Wconversion选项,但没有效果,因为bool和enum对于g++似乎大小相同。(据我所知,enum类型的大小未在规范中定义) 我仔细阅读了gcc手册,但没有发现任何相关内容 问题: 在这种情况下,有没
typedef枚举
{
福,
酒吧,
巴兹
}富特;
静态无效afunc(布尔值为开)
{
/*做好这项工作*/
}
内部主(空)
{
afunc(BAZ);
返回0;
}
编译此代码不会生成任何警告消息,即使给编译器提供了-Wall-Wextra
选项。我甚至尝试过使用-Wconversion
选项,但没有效果,因为bool
和enum
对于g++似乎大小相同。(据我所知,enum
类型的大小未在规范中定义)
我仔细阅读了gcc手册,但没有发现任何相关内容
问题:
- 在这种情况下,有没有办法强制编译器生成警告 是不是C++的规范对这个隐式的铸造是合法的?
编辑的 结论: 唯一可行的解决方案似乎是定义一个新类型来表示0或1,并使用它来代替
bool
代码如下所示,g++抱怨类型转换:
typedef枚举
{
FOO1,
食物2
}富特;
类型定义枚举
{
我的错,
我的话是真的
}我的兄弟;
void foo(我的兄弟)
{
}
内部主(空)
{
/*
*gcc生成一个错误。
*错误:无法将“foo\u t”转换为“my\u bool\t”
*对于参数“1”到“void foo(my_bool_t)”的情况
*/
foo(FOO1);
返回0;
}
是的,这些隐式转换是完全合法的
C++11草案n3290,§4.12布尔转换:
算术、非范围枚举、指针或指向成员类型的指针的prvalue可以转换为
bool类型的pr值。零值、空指针值或空成员指针值转换为false;
任何其他值都将转换为true。std::nullptr_t类型的prvalue可以转换为的prvalue
类型布尔;结果值为false
关于这些转换(算术类型)的警告可能会导致各地出现大量警告,我认为这是不可管理的
在C++11中,可以使用作用域枚举来防止隐式转换:
由于缺少从Foo
到bool
的转换,因此无法编译:
enum class Foo { ONE };
void tryit(bool b) { }
int main()
{
tryit(Foo::ONE);
}
谢谢你,马特。如果它是由C++规范合法的,那么我想实现我想要的唯一方法就是为项目只使用一个新的布尔类型,这样项目的成员就不会犯错误,比如代码片段。我想我应该求助于typedef解决方案,它实际上是有效的。通常,您不需要这样做。但是在某些情况下,比如你正在重构别人的代码,如果没有这种“严格的”类型检查,你会后悔的。也许我应该使用lint。@orchistro:如果可能的话,试着在gcc上升级到一个新版本(我知道这不容易…)。gcc 4.1.x是一个相当古老的分支。@MatthieuM。我非常愿意这样做。我是最后一个不欢迎编译器升级的人。但是,公司不允许这样做。“我想这就是问题所在,我愤怒是因为我在工作的4.3个分支上被卡住了,所以我当然可以移情。因为C++的类型系统只对用户定义的类型好,对于内置的类型,它总是很糟糕。是的,似乎是这样。我决定用typedef定义一个新类型,专门用来表示0或1,并用它来代替bool,bool似乎是用来表示true或false的。