为什么我可以在C中设置一个等于另一个的匿名枚举而不是C ++?

时间:2010-03-18 23:40:58

标签: c++ c compiler-construction

我有以下代码段:

enum { one } x;
enum { two } y;
x = y;

那将在C中编译,但在C ++中,我收到以下错误:

test.c:6: error: cannot convert ‘main()::<anonymous enum>’ to ‘main()::<anonymous enum>’ in assignment

有人可以向我解释为什么会这样吗?我更倾向于回答一些关于编译器为什么会这样做的细节,而不仅仅是“你不能那样做”

3 个答案:

答案 0 :(得分:34)

从一个枚举类型转换为另一个枚举类型通过整数类型(可能是源的基础类型,不确定)。

C和C ++都允许从枚举到整数类型的隐式转换。在C中允许从整数类型到枚举的隐式转换,但在C ++中则不允许。

基本上,C ++更安全。它试图阻止你这样做:

enum {zero, one, two} x;

x = 143; // assigns a value outside the range of the enum

如果要在C ++中执行此枚举转换,可以使用typeof / declspec / boost typeof或等效类型。在海湾合作委员会:

int main() {
    enum {zero, one, two} x;
    enum {zero1, one1, two1} y = two1;
    typedef typeof(x) xtype;
    x = static_cast<typeof(x)>(y);
}

但这样做通常没有意义。对于大多数目的,枚举(尤其是匿名的)是“枚举类型”。它们碰巧被C和C ++标准“实施”为戴着滑稽帽子的整数,但这并不意味着red“等于”hammer只是因为它们各自首先出现在两个不同的枚举(分别是颜色和工具)。 static_cast表明所涉及的两种类型之间存在关联。任何两个枚举类型都是“相关的”,因为它们都有一个基础整数类型,而且它们是相关的,所以“关系”实际上并没有多说。如果你编写这段代码,你会得到一个非常糟糕的类型安全版本。

答案 1 :(得分:1)

我的猜测是,这是由于C ++中更严格的输入。

在C x = 5;中也编译。在C ++中它不会,因为没有定义类型转换。这就是为什么x = y不能编译的原因。

您可以查看this example on codepad,它提供了比编译器更详细的错误说明。

答案 2 :(得分:0)

编译器不知道如何将一个枚举数据类型隐式转换为另一个。

请尝试以下操作。

enum typeX { one } x;
enum typeY { two } y;
x = (typeX) y;