Подтвердить что ты не робот

Почему я могу установить анонимное перечисление, равное другому в C, но не С++?

У меня есть следующий фрагмент кода:

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

Это будет скомпилировано в C, но в С++ я получаю следующую ошибку:

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

Может кто-нибудь объяснить мне, почему это происходит? Я бы предпочел ответ с некоторыми особенностями, почему компилятор ведет себя таким образом, а не просто "Вы не можете этого сделать"

4b9b3361

Ответ 1

Преобразование из одного типа перечисления в другой осуществляется через целочисленный тип (возможно, базовый тип источника, не уверен).

Неявное преобразование из enum в целочисленный тип допускается как на C, так и на С++. Неявное преобразование из целочисленного типа в перечисление разрешено в C, но не в С++.

В принципе, С++ более безопасен по типу. Он пытается остановить вас:

enum {zero, one, two} x;

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

Если вы хотите выполнить это преобразование enum-enum в С++, вы можете использовать typeof/declspec/boost typeof или эквивалент. В GCC:

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

Как правило, нет смысла делать это. Для большинства целей перечисления (и особенно анонимные) являются "перечисляемыми типами". Они просто реализуются по стандартам C и С++ как целые числа в забавных шляпах, но это не означает, что red "равно" hammer только потому, что каждый из них появляется сначала в двух разных перечислениях ( цвета и инструменты соответственно). static_cast предполагает, что существует взаимосвязь между этими двумя типами. Любые два типа перечисления "связаны" тем, что оба имеют базовый целочисленный тип, и они связаны между собой, поэтому "отношение" там действительно мало говорит. Если вы напишете этот код, вы получите довольно бедную версию безопасности типов.

Ответ 2

Я предполагаю, что это связано с более строгой типизацией на С++.

В C x = 5; также компилируется. В С++ это не будет, потому что нет определенного преобразования типов. Это та же самая причина, почему х = у не компилируется.

Вы можете посмотреть этот пример в кодексе, который дает более подробное описание ошибки, чем ваш компилятор.

Ответ 3

Компилятор не знает, как неявно преобразовывать один перечислимый тип данных в другой.

Попробуйте следующее.

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