Search code examples
c++cenumscompilationpacking

C++ packing a typedef enum


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

When I try to compile this with C++ Compiler, I am getting errors, but it seems to work fine with a C compiler. So here's the question. Is it possible to pack an enum in C++, or can someone see why I would get the error?

The error is:

"semicolon missing after declaration of BeNeLux".

I know, after checking and rechecking, that there definitely is a semicolon there, and in any places required in the rest of the code.

Addendum:

_PACKAGE_ was just an example. I am renaming it.

_ASSOCIATIONS_ is not a type of BeNeLux:

#define _ASSOCIATIONS_ __attribute__((packed))

The code is iffed, but only to make sure it is GNU C/C++.

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

Would this cause problems? I thought (GNUC) worked for both C and C++

Addendum 2:

I even tried

#ifdef __cplusplus
extern "C" {
#endif

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

#ifdef __cplusplus
}
#endif

No joy. Anyone?

Note: -fshort-enums is not a possibility; looking for a programmatic solution.


Solution

  • UPDATE:

    For C++11 and later, you can specify the underlying type of enums. For example:

    enum BeNeLux : uint8_t {
       BELGIUM,
       NETHERLANDS,
       LUXEMBURG
    };
    

    But this only applies if the code will be C++ only. If the code needs to be compatible with both C and C++, I believe my original answer still applies.


    I don't think that there is something that does exactly what you want here. I assume you are trying to create a type that is the smallest type for the enum's range.

    If you need this type of control, I would recommend something like this:

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

    not quite as pretty and possibly a little less type safe. But has the effect that you want. sizeof(BeNeLux) == 1 and you have a named constant for all values in the range. A good compiler won't even allocate a variable for static const integer values so long as you never attempt to use the address of it.