Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 994
Sagar Avatar asked May 07 '10 21:05

Sagar


2 Answers

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.

like image 187
Evan Teran Avatar answered Sep 21 '22 15:09

Evan Teran


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

This seems to compile in my g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)

like image 42
Meera Avatar answered Sep 21 '22 15:09

Meera