C/C++: size of a typedef struct containing an int and enum == sizeof(int)?
我在Ubuntu(i686)上使用gcc版本4.3.3。我已经编写了一个简化的测试程序来描述我的理解和问题。该程序将告诉我实现的结构的大小。所以我有一个Message的typedef结构和一个主要的玩法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> typedef struct { int size; enum {token=0x123456}; } Message; int main(int argc, char * argv[]) { Message m; m.size = 30; printf("sizeof(int): %d\ ",sizeof(int)); printf("sizeof(0x123456): %d\ ",sizeof(0x123456)); printf("sizeof(Message): %d\ ",sizeof(Message)); printf("sizeof(m): %d\ ",sizeof(m)); } |
使用gcc编译此源代码时,收到以下警告,我不理解:
1 2 | $ gcc sizeof.c sizeof.c:5: warning: declaration does not declare anything |
第5行是枚举行。我想要在我创建的每个消息中使用该令牌。我究竟做错了什么?我必须更改些什么才能消除该警告?
我的主要对象包含几个sizeof()调用。当我运行程序时,您可以在输出中看到整数的大小为4,十六进制数的大小为4,但是typedef struct Message的大小也为4:
1 2 3 4 5 | $ ./a.out sizeof(int): 4 sizeof(0x123456): 4 sizeof(Message): 4 sizeof(m): 4 |
这让我很困惑。为什么Message的大小为4,尽管它包含一个整数和一个枚举内的整数,每个整数的大小为4。如果sizeof(Message)至少为8,则对我而言是合乎逻辑的。
但是为什么只有4个呢?如何获得邮件的实际大小(以字节为单位)?还是这真的是实际大小?如果是这样,为什么?
在C和C ++之间获取消息的大小是否有所不同?
枚举实际上不需要任何空间,它只是编译器通过名称识别一组文字数字的一种方式。
您没有通过以下方式声明任何内容:
1 | enum {token=0x123456}; |
您的声明类似于:
1 2 3 4 | typedef struct { int size; int; } Message; |
如果您这样声明结构:
1 2 3 4 | typedef struct { int size; enum {token=0x123456} e; } Message; |
将有两个字段,但是
实现所需目标的正确方法是在C ++中使用构造函数:
1 2 3 4 5 | struct Message { int size; int token; Message() : token(0x123456) {}; }; |
或C ++ 11中的非静态数据成员初始化器:
1 2 3 4 | struct Message { int size; int token=0x123456; }; |
无法在C中的struct声明中初始化字段。
1 2 3 4 | typedef struct { int size; enum YouShouldDeclareAName {token=0x123456}; } Message; |
您的枚举是Message结构的子类/子类型,因此绑定到Class而不是对象。就像一个命名空间。您不使用它创建任何变量。
更改为:
1 2 3 4 5 6 7 | typedef struct { int size; enum YouShouldDeclareAName {token=0x123456} token; //or YouShouldDeclareAName token2; } Message; |
第5行没有声明任何枚举类型的变量。因此,编译器会做唯一的事情:忽略它。
如果要在结构中创建该类型的成员,请编写如下内容
1 | enum {token=0x123456} thetoken; |
但是请注意,该字段只能有一个有效值,这就是您想要的吗?
编辑:
哦,并回答您的另一个问题:当编译为C或C ++时,我看不出输出的差异。但是如何编写结构定义之间有区别。
正如其他答案所指出的那样,您已经声明了枚举类型,而您恰好是在结构内部而不是在全局范围内执行此操作。没有什么可存储的,因此它不占用任何内存。
现在,如果要在该结构中声明枚举的实例...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | typedef struct { int size; enum {token=0x123456} e; } Message; int main(int argc, char * argv[]) { Message m; m.size = 30; printf("sizeof(m): %d\ ",sizeof(m)); } sizeof(m): 8 Press any key to continue . . . |
您已经定义了在所有对象之间共享的常量
第5行:
1 | enum {token=0x123456}; |
该行没有定义任何
正确用法应为:
1 | enum {xyz=5} enum_variable_name; |
只有这样编译器才会为此分配空间。
就像类,函数,枚举一样,静态元素不会存储在对象空间中!