Переопределение базового типа перечисления с использованием прагмы или изменения кода

Проблема:

Я использую большую кодовую базу C/C++, которая работает на компиляторах gcc и visual studio, где базовый тип enum по умолчанию 32-битный (целочисленный тип).

Этот код также имеет множество встроенных сборок + встроенных, которые рассматривают enum как целочисленный тип, а данные enum используются во многих случаях как 32-битные флаги.

Когда мы скомпилировали этот код с помощью компилятора realview ARM RVCT 2.2, у нас появилось много проблем, поскольку компилятор realview автоматически определяет базовый тип перечисления на основе значения, заданного для перечисления. http://www.keil.com/support/man/docs/armccref/armccref_Babjddhe.htm

Например,

Рассмотрим перечисленное ниже,

enum Scale {
    TimesOne, //0
    TimesTwo, //1
    TimesFour, //2
    TimesEight, //3
};

Это перечисление используется как 32-битный флаг. но компилятор оптимизирует его до типа unsigned char для этого перечисления.

Использование параметра компилятора --enum_is_int не является хорошим решением для нашего случая, поскольку он преобразует все перечисления в 32-битные, что нарушает взаимодействие с любым внешним кодом, скомпилированным без --enum_is_int.

Это предупреждение, которое я нашел в компиляторах RVCT и руководстве по библиотеке,

Параметр --enum_is_int не рекомендуется для общего использования и не требуется для ISO-совместимого источника. Код, скомпилированный с этой опцией, не совместим с ABI для архитектуры ARM (базовый стандарт) [BSABI], и неправильное использование может привести к сбою во время выполнения. Эта опция не поддерживается библиотеками C++.

Вопрос

Как преобразовать весь базовый тип enum (путем внесения изменений вручную) в 32-битный, не влияя на порядок значений?

enum Scale {
    TimesOne=0x00000000,
    TimesTwo, // 0x00000001
    TimesFour, // 0x00000002
    TimesEight, //0x00000003
};

Я попробовал вышеуказанное изменение. Но компилятор оптимизирует это и для нашей неудачи.:(

В.NET есть некоторый синтаксис

enum Scale: int

Это стандарт ISO C++, а компилятору ARM его не хватает?

В компиляторе ARM RVCT 2.2 отсутствует #pragma для управления этим перечислением. Есть ли в наличии скрытая прагма?

2 ответа

Решение

Я знаю, что многие заголовки Windows используют следующее:

enum SOME_ENUM {
    ONE = 1,
    TWO = 2,
    //...
    FORCE_DWORD = 0x7FFFFFFF
};

В C++ 11:

enum class Scale : uint32_t {
   TimesOne, //0
   TimesTwo, //1
   TimesFour, //2
   TimesEight, //3
};

Visual Studio 2012 и gcc 4.4.6 с опцией -std= C++0x оба поддерживают это (более ранние версии также могут.)

Другие вопросы по тегам