C++ упаковка перечисления typedef

typedef enum BeNeLux
{
   BELGIUM,
   NETHERLANDS,
   LUXEMBURG
} _ASSOCIATIONS_ BeNeLux;

Когда я пытаюсь скомпилировать это с помощью компилятора C++, я получаю ошибки, но, похоже, он работает нормально с компилятором C. Итак, вот вопрос. Можно ли упаковать перечисление в C++, или кто-то может понять, почему я получаю ошибку?

Ошибка:

msgstr "точка с запятой отсутствует после объявления BeNeLux".

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

Приложение:

_PACKAGE_ был просто примером. Я переименовываю это.

_ASSOCIATIONS_ это не тип BeNeLux:

#define _ASSOCIATIONS_ __attribute__((packed))

Код не указан, но только для того, чтобы убедиться, что это GNU C/C++.

#if defined (__GNUC__) 
#define _ASSOCIATIONS_ __attribute__((packed))
#else
#define _ASSOCIATIONS_

Это вызовет проблемы? Я думал (GNUC) работал как для C, так и для C++

Приложение 2:

Я даже пытался

#ifdef __cplusplus
extern "C" {
#endif

    typedef enum BeNeLux
    {
       BELGIUM,
       NETHERLANDS,
       LUXEMBURG
    } _ASSOCIATIONS_ BeNeLux;

#ifdef __cplusplus
}
#endif

Нет радости Кто-нибудь?

Примечание: -fshort-enums не возможен; ищу программное решение.

7 ответов

Решение

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

Если вам нужен этот тип контроля, я бы порекомендовал что-то вроде этого:

typedef unsigned char BeNeLux;
static const BeNeLux BELGIUM = 0;
static const BeNeLux NETHERLANDS = 1;
static const BeNeLux LUXEMBURG = 2;

не так красиво и, возможно, немного менее безопасно. Но имеет эффект, который вы хотите. sizeof(BeNeLux) == 1 и у вас есть именованная константа для всех значений в диапазоне. Хороший компилятор даже не выделит переменную для static const целочисленные значения, если вы никогда не пытаетесь использовать его адрес.

#if defined (__GNUC__)
#  if defined (__cplusplus)
#     define _ASSOCIATIONS_(X) __attribute__((packed))
#  else
#     define _ASSOCIATIONS_(X) __attribute__((packed)) X
#  endif
#else
#  if defined (__cplusplus)
#     define _ASSOCIATIONS_(X)
#  else
#     define _ASSOCIATIONS_(X) X
#  endif
#endif

typdef enum BeNeLux {
  BELGIUM,
  NETHERLANDS,
  LUXEMBURG
} _ASSOCIATIONS_ (BeNeLux);

Это, кажется, скомпилировать в моем g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)

Здесь нет настоящих прорывов. Я просто изменил порядок вещей в надежде, что вашему компилятору это понравится больше. У меня не было вашей версии gcc или g ++, поэтому я не смог протестировать их. Я запускал его через версии 3.4.5 gcc и g ++ (mingw special), которые оба предупреждали 'packed' attribute ignored при заказе понравился твой код, но не пожаловался на мой.

#ifdef __GNUC__
#define attribute(x) __attribute__((x));
#else
#define attribute(x)
#endif


#ifdef __cplusplus
extern "C" {
#endif

enum BeNeLux
{
    BELGIUM,
    NETHERLANDS,
    LUXEMBURG
} attribute(packed);
// I declared attribute to look like a f() so that it would not look like I was
// declaring a variable here.

#ifndef __cplusplus
typedef enum BeNeLux BeNeLux; // the typedef is separated into a separate stmt
#else
}
#endif
enum BeNeLux
{
   BELGIUM,
   NETHERLANDS,
   LUXEMBURG
};

Это то, что ожидается от кода C++.

Я полагаю, вы используете GCC и G++. Для меня код компилируется нормально. Было бы довольно удивительно видеть, что такая функция исчезает при включении C++ на любом конкретном компиляторе.

Убедитесь, что ваш #define не является #ifВычеркнуто для кода C++, например #ifndef __cplusplus,

Пытаться g++ -E чтобы увидеть выходные данные препроцессора и убедиться, что #define появляется.

Кроме того, даже для макросов препроцессора имена, начинающиеся с символа подчеркивания и заглавной буквы или двух символов подчеркивания, зарезервированы для компилятора и библиотеки. Если вам нужен макрос, PACKED может быть лучшим названием для этого.

В C++ вам не нужны typedef, Просто начни с enum BeNeLux, Также возможно (я никогда не смогу вспомнить), что объявление типа и переменной с одним и тем же идентификатором может быть недопустимым на одном из языков.

#if defined (__GNUC__)

#  if defined (__cplusplus)
#     define ENUM enum
#  else
#     define ENUM typedef enum
#  endif

#  if defined (__cplusplus)
#     define _ASSOCIATIONS_(X) __attribute__((packed))
#  else
#     define _ASSOCIATIONS_(X) __attribute__((packed)) X
#  endif
#else
#  if defined (__cplusplus)
#     define _ASSOCIATIONS_(X)
#  else
#     define _ASSOCIATIONS_(X) X
#  endif
#endif

ENUM BeNeLux {
  BELGIUM,
  NETHERLANDS,
  LUXEMBURG
} _ASSOCIATIONS_ (BeNeLux);

Еще один фрагмент. увидеть новое #define ENUM

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