为什么这两个结构定义编译正常:
struct foo {
int a;
} __attribute__((packed));
typedef struct __attribute__((packed)) {
int a;
} bar;
Run Code Online (Sandbox Code Playgroud)
虽然这个发出警告:
typedef struct {
int a;
} baz __attribute__((packed));
warning: ‘packed’ attribute ignored [-Wattributes]
Run Code Online (Sandbox Code Playgroud)
这一个给出了错误和警告:
typedef struct qux __attribute__((packed)) {
int a;
} qux;
error: expected identifier or ‘(’ before ‘{’ token
warning: data definition has no type or storage class [enabled by default]
Run Code Online (Sandbox Code Playgroud)
作为新手C程序员,最后两个定义不起作用的事实似乎是语言设计者/编译器编写者的一个相当随意的选择.是否有一个原因?我正在使用gcc 4.7.3.
typedef struct __attribute__((packed)) {
int a;
} bar;
Run Code Online (Sandbox Code Playgroud)
VS
typedef struct {
int a;
} baz __attribute__((packed));
Run Code Online (Sandbox Code Playgroud)
在第一个你说"考虑这个匿名结构,包含属性,有一个成员a.然后为这个结构创建一个别名,并命名为'bar'".用于描述结构而不是匿名执行并且必须键入def的正常语法是
struct bar { int a; };
Run Code Online (Sandbox Code Playgroud)
在第二个声明中你说"考虑这个匿名结构,它有一个成员a.然后为这个结构创建一个别名,并命名'baz who packed'".
它不起作用,因为您尝试将该属性应用于typedef中的别名,而不是结构定义.
typedef <entity> <alias>;
Run Code Online (Sandbox Code Playgroud)
我会建议你使用"typedef"语法来描述结构:)
它在前两个实例中起作用的原因是因为__attribute__((packed))只能应用于struct,union或enum。在第一个示例中,您声明一个struct被调用的foo,在第二个示例中您声明一个struct被调用的bar。在第二个示例中,typedef将变量声明转换为类型声明。
您的第三个示例是声明一个名为的变量baz并尝试将其声明为打包的。由于打包信息附加到类型而不是实例,因此这是没有意义的,并且编译器会忽略它。
除非你确切地知道自己在做什么,否则你真的不应该使用Packed。一方面,__attribute__它不是标准 C。它是一个gcc扩展,因此不能与任何其他编译器一起使用。
另一方面,真正需要它的情况很少。例如,在上面的代码中,即使在前两个实例中,它也是无操作的,因为打包会删除成员之间的空间,并且每个struct. 打包结构不是默认值的原因是,通用数据类型在特定边界上对齐时效果更好。例如,int如果在四的倍数的内存位置上对齐,对 an 的访问将执行得更好。有关详细信息,请参阅有关数据结构对齐的 wiki 条目。