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

StackOverflow https://stackoverflow.com/questions/2521200

  •  22-09-2019
  •  | 
  •  

Вопрос

Проблема:

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top