переопределение базового типа перечисления с помощью pragma или изменения кода
Вопрос
Проблема:
Я использую большую базу кода 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 есть некоторый синтаксис, подобный
шкала перечисления:инт
Является ли это стандартом ISO C ++ и компилятору ARM его не хватает?
В компиляторе ARM RVCT 2.2 нет #pragma для управления этим перечислением.Доступна ли какая - нибудь скрытая прагма ?
Решение
Я знаю, что многие заголовки 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 поддерживают это (более ранние версии также могут.)