3

我在我的 Ubuntu (i686) 上使用 gcc 版本 4.3.3。我写了一个精简的测试程序来描述我缺乏理解和我的问题。该程序将告诉我我实现的结构的大小。所以我有一个用于Message的typedef 结构和一个小 main 来玩:

#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\n",sizeof(int));
    printf("sizeof(0x123456): %d\n",sizeof(0x123456));
    printf("sizeof(Message): %d\n",sizeof(Message));
    printf("sizeof(m): %d\n",sizeof(m));
}

使用 gcc 编译此源时,我收到以下警告,我不明白:

$ gcc sizeof.c
sizeof.c:5: warning: declaration does not declare anything

第 5 行是指枚举行。我希望在我创建的每条Message中都使用该令牌。我究竟做错了什么?我必须改变什么才能摆脱该警告?

我的 main 包含几个sizeof()调用。当我运行程序时,您可以在输出中看到整数的大小为 4,十六进制数的大小为 4,但 typedef struct Message 的大小也为 4:

$ ./a.out
sizeof(int): 4
sizeof(0x123456): 4
sizeof(Message): 4
sizeof(m): 4

这让我很困惑。为什么Message的大小为 4,尽管它在枚举中包含一个整数和一个整数,每个整数的大小为 4。如果sizeof(Message)至少为 8,这对我来说是合乎逻辑的。

但是为什么只有4个?如何以字节为单位获得消息的实际大小?或者这真的是真实尺寸吗?如果是这样,为什么?

在 C 和 C++ 之间获取消息的大小有区别吗?

4

8 回答 8

10

枚举实际上不需要任何空格,它只是编译器通过名称识别一组文字数字的一种方式。

于 2012-06-14T12:07:35.560 回答
4

您没有声明任何内容:

enum {token=0x123456};

您的声明类似于:

typedef struct {
    int size; 
    int; 
} Message;

如果你这样声明你的结构:

typedef struct {
    int size; 
    enum {token=0x123456} e; 
} Message;

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

实现您想要的正确方法是在 C++ 中使用构造函数:

struct Message {
    int size; 
    int token;
    Message() : token(0x123456) {}; 
};

或 C++11 中的非静态数据成员初始化器:

struct Message {
    int size; 
    int token=0x123456;
};

无法在 C 中初始化结构声明中的字段。

于 2012-06-14T12:33:43.867 回答
3

第 5 行没有声明任何枚举类型的变量。所以编译器做它唯一能做的事:忽略它。

如果要在结构中创建该类型的成员,请编写类似

enum  {token=0x123456} thetoken;

但请注意,该字段只能有一个有效值,这是您想要的吗?

编辑
哦,回答你的另一个问题:编译为 C 或 C++ 时,我看不到输出的差异。但是如何编写结构定义是有区别的。

于 2012-06-14T12:08:18.213 回答
3
typedef struct {
    int size; 
    enum YouShouldDeclareAName {token=0x123456}; 
} Message;

您的枚举是您的消息结构的子类/子类型,因此绑定到类而不是对象。就像一个命名空间。您不会使用它创建任何变量。将其更改为:

typedef struct {
    int size; 
    enum YouShouldDeclareAName {token=0x123456} token; 

    //or
    YouShouldDeclareAName token2;
} Message;
于 2012-06-14T12:11:38.193 回答
2

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

于 2012-06-14T12:06:10.193 回答
2

正如其他人的回答所指出的那样,您已经声明了一个枚举类型,您只是碰巧在结构内而不是在全局范围内进行了操作。没有什么可存储的,所以它不使用内存。

现在,如果您要在该结构中声明您的枚举实例...

typedef struct {
    int size; 
    enum {token=0x123456} e; 
} Message;

int main(int argc, char * argv[])
{
    Message m;
    m.size = 30;
    printf("sizeof(m): %d\n",sizeof(m));
}

sizeof(m): 8
Press any key to continue . . .
于 2012-06-14T12:14:39.460 回答
1

第 5 行:

enum {token=0x123456};

这一行没有定义任何enum变量,它是一个声明,因此你的编译器抱怨第 5 行说它只是一个声明。

正确的用法应该是:

enum {xyz=5}  enum_variable_name;

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

于 2012-06-14T13:04:21.493 回答
0

就像类、函数、枚举一样,静态成员不存储在对象空间中!

于 2012-06-14T12:12:34.997 回答