2010-05-07 20 views
5
typedef enum BeNeLux 
{ 
    BELGIUM, 
    NETHERLANDS, 
    LUXEMBURG 
} _ASSOCIATIONS_ BeNeLux; 

Kiedy próbuję skompilować to za pomocą kompilatora C++, otrzymuję błędy, ale wydaje się, że działa dobrze z kompilatorem C. Oto pytanie. Czy możliwe jest spakowanie enum w C++, czy ktoś może zobaczyć, dlaczego dostanę błąd?C++ pakowanie wyliczenia typedef

Błąd jest:

"średnik brakuje po deklaracji Beneluksu".

Wiem, po sprawdzeniu i ponownym sprawdzeniu, że tam zdecydowanie znajduje się tam średnik oraz w miejscach wymaganych w pozostałej części kodu.

Uzupełnienie:

_PACKAGE_ był tylko przykład. Zmieniam jego nazwę.

_ASSOCIATIONS_ nie jest typem Beneluksu:

#define _ASSOCIATIONS_ __attribute__((packed))

Kod jest iffed, ale tylko upewnić się, że jest GNU C/C++.

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

Czy to może powodować problemy? Pomyślałem (GNUC) pracował zarówno dla C i C++

Addendum 2:

Próbowałem nawet

#ifdef __cplusplus 
extern "C" { 
#endif 

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

#ifdef __cplusplus 
} 
#endif 

No radość. Ktoś?

Uwaga: -wybrane-wyrazy nie są możliwe; szukanie rozwiązania programowego.

+2

Co oznacza '_PACKAGE_'? – wilhelmtell

+0

To jest niestandardowa funkcja. Z jakiego kompilatora C korzystasz? – Potatoswatter

+0

Używanie gcc w wersji 3.3.5 lub niższej (musisz użyć tej starszej wersji) – Sagar

Odpowiedz

1

Nie sądzę, że istnieje coś, co robi dokładnie co chcesz tutaj. Zakładam, że próbujesz stworzyć typ, który jest najmniejszy dla zakresu enum.

Jeśli potrzebujesz tego typu kontroli, polecam coś takiego:

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

nie tak ładny i ewentualnie trochę mniej bezpieczny typ. Ale ma efekt, który chcesz. sizeof(BeNeLux) == 1 i masz nazwaną stałą dla wszystkich wartości w zakresie. Dobry kompilator nie przydzieli nawet zmiennej dla wartości całkowitych static const, o ile nigdy nie spróbujesz użyć jej adresu.

+0

Dziękuję, proszę pana! To zadziałało niesamowicie: D – Sagar

0

Przypuszczam, że używasz GCC i G ++. Kod kompiluje się dobrze albo dla mnie. Zaskakujące byłoby zobaczenie, że taka cecha znika po włączeniu C++ w dowolnym konkretnym kompilatorze.

Upewnij się, że Twój #define nie jest #if "ed dla kodu C++, np. #ifndef __cplusplus.

Wypróbuj g++ -E, aby zobaczyć dane wyjściowe preprocesora i sprawdź, czy pojawi się #define.

Również dla makr preprocesorów nazwy zaczynające się znakiem podkreślenia i wielką literą lub dwoma podkreśleniami są zarezerwowane dla kompilatora i biblioteki. Jeśli musisz mieć makro, najlepszą nazwą może być PACKED.

+0

Dodał ten kod bezpośrednio bez #if i nadal nie działał. – Sagar

+0

@Sagar: wypróbuj zarówno 'gcc -v', jak i' g ++ -v', aby upewnić się, że otrzymujesz tę samą wersję obu. – Potatoswatter

+0

Zgodnie z instrukcją http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC105 powinno to działać nawet w GCC 2.95. – Potatoswatter

0

W języku C++ nie potrzebujesz typedef. Zacznij od enum BeNeLux. Możliwe jest również (nigdy nie pamiętam), że deklarowanie typu i zmiennej o tym samym identyfikatorze może nie być legalne w jednym z języków.

+0

addendum wyjaśnia, że ​​nie tego chce. Deklaracja typu i identyfikatora jednocześnie jest niemożliwa w obu językach. – Potatoswatter

+0

Mam na myśli, że zadeklarowanie 'typedef' i identyfikatora jednocześnie jest niemożliwe w obu. – Potatoswatter

+0

@Potatoswatter: Huh? –

0
enum BeNeLux 
{ 
    BELGIUM, 
    NETHERLANDS, 
    LUXEMBURG 
}; 

Tego właśnie oczekuje się od kodu C++.

+0

addendum wyjaśnia, że ​​nie tego chce. – Potatoswatter

+0

Nie, nie ma. Gdyby tego użył, byłby skończony. – Puppy

+0

Nie. Pytanie dotyczy "typedef enum" i pakowania atrybutów. Wiem, że enum BeNeLux zadziała, ale to nie jest to, czego potrzebuję. – Sagar

1
#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); 

To wydaje się skompilować w moim g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)

+0

Cześć Meera, działa dla nas z wersjami g ++ powyżej 4. Problem polega na tym, że musimy użyć wersji 3.3.5 lub niższej (powyżej komentarzy). – Sagar

+0

Zrobiłem kolejną próbę ... http://stackoverflow.com/questions/2791739/c-packing-a-typedef-enum/2916024#2916024 – Meera

1

Nie ma tutaj prawdziwych przełomów. Właśnie zmieniłem porządek w nadziei, że Twój kompilator polubi to lepiej. Nie miałem Twojej wersji gcc lub g ++, więc nie mogłem z nimi przetestować. Uruchomiłem go w wersji 3.4.5 gcc i g ++ (mingw special), które ostrzegły o tym, że jest to Twój kod, ale nie narzekam na moje.

#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 
0
#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); 

Kolejny fragment. zobacz nowy #define ENUM