переопределение базового типа перечисления с использованием прагмы или изменения кода - PullRequest
1 голос
/ 26 марта 2010

Проблема:

Я использую большую кодовую базу 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 ++.

Вопрос

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

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

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

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

enum Scale: int

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

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

Ответы [ 2 ]

4 голосов
/ 26 марта 2010

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

enum SOME_ENUM {
    ONE = 1,
    TWO = 2,
    //...
    FORCE_DWORD = 0x7FFFFFFF
};
0 голосов
/ 26 февраля 2013

В 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 оба поддерживают это (ранние версии также могут.)

...