单成员结构的结构填充 [英] Struct padding for single member structs

查看:106
本文介绍了单成员结构的结构填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直想制作一个任意大小的结构,在编译时就知道了. (用于宏).

I was looking to make a struct which was an arbitrary size, known at compile time. (for use in a macro).

例如:

/* assume sizeof(SomeStruct) could be an odd number,
 * if it is using GCC's 'packed' attribute for eg */
struct {
    unsigned char data[sizeof(SomeStruct)];
} a, *tmp;

tmp = (void *)some_data
a = *tmp;

但是,我担心struct填充可能会增加struct的大小,因此它大于成员的大小,因此向我保证,单个成员struct的大小将始终是其成员的大小

However I was concerned that struct padding may increase the size of the struct so it is larger than the member, I was assured that the size of a single member struct will always be the size of its member.

所以我的问题是:

我可以一直依赖与它们的成员大小相同的单个成员结构 吗?这是C规范的一部分吗?还是大多数编译器的行为方式?

Can I rely on single member structs always being the same size as their member? Is this apart of the C spec? or is it just how most compilers behave?

推荐答案

C11 6.7.2.1 paragraph 17:

结构或联合的末尾可能存在未命名的填充.

There may be unnamed padding at the end of a structure or union.

对于只有一个成员的结构,没有列出特殊情况.这是实现定义的.

No special case is listed for structs with only one member. This is implementation-defined.

编译器为什么会在其中填充空格并不太清楚,因为成员的大小应该已经为所有目的所必需地进行了填充,因为它具有自己的完整类型.

It's not obvious why a compiler would put padding there though, since the size of the member should already be as padded as is necessary for all purposes, as it has a complete type of its own.

不过,对于您的用法,您不必依赖编译器的行为-您可以通过向宏sizeof *tmp == sizeof (SomeStruct)中添加静态断言来自己执行该行为.如果您使用的是最新的编译器,并且您的宏允许使用声明语句,则只需使用_Static_assert;否则,请使用_Static_assert.您还可以使用几种与C99兼容的黑客,例如:

For your usage though, you don't need to rely on the compiler's behaviour - you can enforce it yourself by adding a static assertion to your macro that sizeof *tmp == sizeof (SomeStruct). If you have an up-to-date compiler and your macro allows for declaration statements, just use _Static_assert; there are also several C99-compatible hacks you can use, such as:

#define STATIC_EXPR_ASSERT(COND) (sizeof (char[(COND) ? 1 : -1]))

...,您可以将其用作逗号表达式.

... which you can use as the lhs of a comma-expression.

您还应该注意,如果临时结构的主体由char数组组成,则它可能没有足够的对齐方式来正确表示传入的数据.从C11开始,您应该使用_Alignas指定数组的对齐方式:

You should also note that if the body of the temporary struct is made up of a char array, it may not have sufficient alignment to represent the incoming data correctly. From C11 onwards you should specify the alignment of the array with _Alignas:

struct {
    _Alignas (max_align_t) unsigned char data[sizeof(SomeStruct)];
} a, *tmp;

...这将确保它可以安全地存储任何类型的数据,而无需对齐.在C99中,您没有任何方法可以显式地请求最大对齐方式,但是您可以通过使临时结构成为并列的联合成员来强制对齐方式来匹配命名类型(您可以尝试long double并希望这是最大的)对齐的类型).

...which will ensure it can safely store the data for any type regardless of alignment. In C99 you don't have any way to explicitly request max alignment, but you can force the alignment to match a named type by making the temporary struct a member of a union alongside it (you might try long double and hope that's the most-aligned type).

这篇关于单成员结构的结构填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆