[英]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.当我尝试使用 C++ Compiler 编译它时,出现错误,但它似乎与 C 编译器一起工作正常。 So here's the question.
那么问题来了。 Is it possible to pack an enum in C++, or can someone see why I would get the error?
是否可以在 C++ 中打包枚举,或者有人可以看到为什么我会收到错误?
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. _PACKAGE_
只是一个例子。 I am renaming it.我正在重命名它。
_ASSOCIATIONS_
is not a type of BeNeLux: _ASSOCIATIONS_
不是比荷卢经济_ASSOCIATIONS_
的类型:
#define _ASSOCIATIONS_ __attribute__((packed))
The code is iffed, but only to make sure it is GNU C/C++.代码是 iffed,但只是为了确保它是 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++
我认为( GNUC )适用于 C 和 C++
Addendum 2:附录 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;注意:-fshort-enums 是不可能的; looking for a programmatic solution.
寻找一个程序化的解决方案。
UPDATE:更新:
For C++11 and later, you can specify the underlying type of enum
s.对于 C++11 及更高版本,您可以指定
enum
的基础类型。 For example:例如:
enum BeNeLux : uint8_t {
BELGIUM,
NETHERLANDS,
LUXEMBURG
};
But this only applies if the code will be C++ only.但这仅适用于代码仅为 C++ 的情况。 If the code needs to be compatible with both C and C++, I believe my original answer still applies.
如果代码需要与 C 和 C++ 兼容,我相信我原来的答案仍然适用。
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. sizeof(BeNeLux) == 1
并且您具有该范围内所有值的命名常量。 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.一个好的编译器甚至不会为
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);
This seems to compile in my g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
这似乎在我的
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.
我没有你的 gcc 或 g++ 版本,所以我无法测试。 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.我确实通过版本 3.4.5 gcc 和 g++(mingw 特殊)运行它,当像您的代码一样订购时,它们都警告
'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
I suppose you're using GCC and G++.我想你正在使用 GCC 和 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.
当在任何一个特定的编译器上启用 C++ 时,看到这样一个特性消失是相当令人惊讶的。
Make sure that your #define
is not #if
'ed out for C++ code, eg #ifndef __cplusplus
.确保您的
#define
不是 C++ 代码的#if
,例如#ifndef __cplusplus
。
Try g++ -E
to see the preprocessor output and verify that the #define
appears.尝试
g++ -E
查看预处理器输出并验证#define
出现。
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.如果您必须有一个宏,
PACKED
可能是它的最佳名称。
In C++, you don't need the typedef
.在 C++ 中,您不需要
typedef
。 Just start with enum BeNeLux
.只需从
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.这是对 C++ 代码的期望。
#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
查看新的
#define ENUM
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.