C++ packing a typedef enum
-
04-10-2019 - |
Pergunta
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.
Solução
I don't think that there is something that does exactly what you want here. I assume you are trying to create a type which 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.
Outras dicas
#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)
There are no real breakthroughs here. I just reordered things in the hopes that your
compiler would like it better. I did not have your version of gcc or g++ so I could not test with those. I did run it through version 3.4.5 gcc and g++ (mingw special) which both warned 'packed' attribute ignored
when ordered like your code, but did not complain about mine.
#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
In C++, you don't need the typedef
. Just start with enum BeNeLux
. It's also possible (I can never remember) that declaring a type and a variable with the same identifier may not be legal in one of the languages.
enum BeNeLux
{
BELGIUM,
NETHERLANDS,
LUXEMBURG
};
This is what is expected of C++ code.
I suppose you're using GCC and G++. The code compiles fine with either, for me. It would be rather suprising to see such a feature disappear when enabling C++ on any one particular compiler.
Make sure that your #define
is not #if
'ed out for C++ code, e.g. #ifndef __cplusplus
.
Try g++ -E
to see the preprocessor output and verify that the #define
appears.
Also, even for preprocessor macros, names beginning with an underscore and capital letter or two underscores are reserved for the compiler and library. If you must have a macro, PACKED
might be the best name for it.
#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);
Another snippet. see the new #define ENUM