C / C ++:包含int和enum == sizeof(int)的typedef结构的大小?

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;

将有两个字段,但是e不会初始化为任何内容。您需要为每个实例手动设置它:message.e=token

实现所需目标的正确方法是在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 . . .

您已经定义了在所有对象之间共享的常量Message::token。由于它是共享的,因此不会计入单个对象的大小。


第5行:

1
enum {token=0x123456};

该行没有定义任何enum变量,而是一个声明,因此,您的编译器会抱怨第5行说它仅是一个声明。

正确用法应为:

1
enum {xyz=5}  enum_variable_name;

只有这样编译器才会为此分配空间。


就像类,函数,枚举一样,静态元素不会存储在对象空间中!