结构打包是确定性的吗? [英] Is struct packing deterministic?

查看:65
本文介绍了结构打包是确定性的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,假设我在不同的项目中有两个等效的结构ab:

For example, say I have two equivalent structs a and b in different projects:

typedef struct _a
{
    int a;
    double b;
    char c;
} a;

typedef struct _b
{
    int d;
    double e;
    char f;
} b;

假设我没有使用任何像#pragma pack这样的指令,并且这些结构是在同一体系结构的同一编译器上编译的,它们在变量之间是否具有相同的填充?

Assuming I haven't used any directives like #pragma pack and these structs are compiled on the same compiler on the same architecture, will they have identical padding between variables?

推荐答案

编译器是确定性的.如果不是这样,则不可能进行单独的编译.具有相同struct声明的两个不同的翻译单元将一起工作; §.6.2.7/1保证的:兼容的类型和组合类型.

The compiler is deterministic; if it weren't, separate compilation would be impossible. Two different translation units with the same struct declaration will work together; that is guaranteed by §6.2.7/1: Compatible types and composite types.

此外,同一平台上的两个不同的编译器应该互操作,尽管标准并不能保证. (这是实现质量的问题.)为了实现互操作性,编译器编写者在平台ABI(应用程序二进制接口)上达成了一致,该平台将包括如何表示复合类型的精确规范.这样,使用一个编译器编译的程序就可以使用通过其他编译器编译的库模块.

Moreover, two different compilers on the same platform should interoperate, although this is not guaranteed by the standard. (It's a quality of implementation issue.) To allow inter-operability, compiler writers agree on a platform ABI (Application Binary Interface) which will include a precise specification of how composite types are represented. In this way, it is possible for a program compiled with one compiler to use library modules compiled with a different compiler.

但是,您不仅对确定性感兴趣;还对确定性感兴趣.您还希望两种不同类型的布局相同.

But you are not just interested in determinism; you also want the layout of two different types to be the same.

根据标准,如果两个struct类型的成员(按顺序获取)兼容,并且它们的标记和成员名称相同,则它们是兼容的.由于示例structs具有不同的标记和名称,因此即使它们的成员类型不同,它们也不兼容,因此您不能在需要另一种的情况下使用其中一种.

According to the standard, two struct types are compatible if their members (taken in order) are compatible, and if their tags and member names are the same. Since your example structs have different tags and names, they are not compatible even though their member types are, so you cannot use one where the other is required.

该标准允许标签和成员名称影响兼容性似乎有些奇怪.该标准要求按声明顺序排列结构的成员,因此名称不能更改结构中成员的顺序.那么,为什么它们会影响填充?我不知道他们在哪里编译器,但是该标准的灵活性基于这样的原则:要求应该是保证正确执行所必需的最低要求.在翻译单元中不允许别名不同的结构,因此无需在不同的翻译单元之间纵容它.因此,该标准不允许这样做. (对于实现,将有关类型的信息插入struct的填充字节中是合法的,即使它需要确定性地添加填充以为此类信息提供空间.唯一的限制是,不能在填充之前放置填充. struct的第一个成员.)

It may seem odd that the standard allows tags and member names to affect compatibility. The standard requires that the members of a struct be laid out in declaration order, so names cannot change the order of members within the struct. Why, then, could they affect padding? I don't know of any compiler where they do, but the standard's flexibility is based on the principle that the requirements should be the minimum necessary to guarantee correct execution. Aliasing differently tagged structs is not permitted within a translation unit, so there is no need to condone it between different translation units. And so the standard does not allow it. (It would be legitimate for an implementation to insert information about the type in a struct's padding bytes, even if it needed to deterministically add padding to provide space for such information. The only restriction is that padding cannot be placed before the first member of a struct.)

平台ABI可能会在不参考其标记或成员名称的情况下指定复合类型的布局.在特定的平台上,如果平台ABI具有这样的规范,并且记录了符合平台ABI的编译器,则可以避免使用别名,尽管从技术上讲这不是正确的,并且显然前提条件使其不可移植

A platform ABI is likely to specify the layout of a composite type without reference to its tag or member names. On a particular platform, with a platform ABI which has such a specification and a compiler documented to conform to the platform ABI, you could get away with the aliasing, although it would not be technically correct, and obviously the preconditions make it non-portable.

这篇关于结构打包是确定性的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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