为什么打包结构不属于C语言?


10

每个C编译器都提供“打包” C结构的选项(例如__attribute__ ((__packed__))#pragma pack())。现在,我们都知道,如果我们想以可靠的方式发送或存储数据,则需要打包。自C语言问世以来,这也一直是必需的。

所以我想知道为什么打包结构不属于C语言规范的一部分?即使几十年来已经知道使用它们的必要性,它们甚至不在C99或C11中?我缺少什么?为什么它是特定于编译器的?


2
他们没有必要写纯C代码。
user253751 2014年

Answers:


7

我猜是因为这取决于所使用的目标CPU /编译器的组合。这意味着最好是成为编译器指令(与之相关)而不是语言方面,因为该如何规范?他们唯一的办法就是工会。

雷蒙德(Raymond)的文章对为什么会这样有一些见解:http : //www.catb.org/esr/structure-packing/


非常有趣的文章。(+1)
乔治

允许代码说“我需要一个包含12个字节的结构;字段X必须表现为32位整数,存储为偏移量为0的四个八位字节little-endian;字段Y必须表现为64位整数,这会有什么困难?存储为字节字节little-endian在偏移量4“?在任何平台上处理该问题的代码都不会比编译器已经为位域所做的事情糟,并且在程序员碰巧指定与本机匹配的对齐方式的情况下,效率可能更高。在其他机器上,它的效率较低,但仍可移植。
超级猫

5

主要有三个因素。

  1. 某些处理器无法访问未对齐的数据(例如,从奇数地址开始的整数或浮点数)。尝试执行会触发异常。
  2. 一些处理器可以访问未对齐的数据,但是会降低性能。
  3. 大多数结构可以通过一组C / C ++源代码访问,并且与其他语言的互操作性是一个例外,而不是规则。

考虑到这些因素,标准编译器和所有C / C ++编译器都会例行填充结构以确保处理器的最佳对齐方式,但也可以提供用于互操作的机制,以在需要时覆盖此结构。

这绝不是被忽略的事情。众所周知,目前的情况是设计使然。最新版本的C ++标准为您可能不熟悉的对齐问题提供了广泛的支持。


可以对压缩结构进行的任何论证也可以用来证明使位域成为可选功能是合理的。在某些处理器上,访问打包结构的成员会很慢,而在另一些处理器上,访问速成结构的成员会很快,但是让编译器尝试用更高效的代码来替换用户代码的变通办法是因为缺少未对齐的访问功能,这比简单地让编译器让程序员指定什么要复杂得多。他们需要。
超级猫

@supercat:您在争论(或反对)什么?我不明白
david.pfx

我认为位域应该是可选的,但是如果位域将成为强制性功能,则以允许显式控制结构布局的方式扩展它们将是有意义的。否则,最终结果是编译器必须完成完全控制布局所需的90%的工作,但是程序员只能从中受益10%。
超级猫

@supercat:位域是整数,并遵循与integers:实现定义相同的位布局排序规则。结构成员按声明的字符边界排序,可能会插入包装。它们在概念上是完全分开的。[如果您想扩展提案,就需要问另一个问题,但我认为这根本行不通。]
david.pfx

0

它是特定于编译器的,因为它不在标准中。而且它不在标准之内,因为对于具有强制对齐限制的晦涩平台的编译器而言,很难以不需要大量实现工作的方式进行指定。

而且,这些努力都没有充分的理由,因为使用C89或更高版本的编译器的任何人都关心的每个编译器/平台都已经实现了。


2
??? 您通过说“因为不符合标准”回答了“为什么不符合标准语言”的问题……
Emilio Garavaglia 2014年

这是我首先想到的,但随后又可以指定一个功能,例如“如果使用关键字“ packed”定义了struct,则其大小可以保证与每个单个成员的增加大小相同。在不支持的平台上未对齐的内存访问,对结构成员值之一的访问是未定义的行为。” 这将允许开发人员在没有无法访问的平台上至少知道结构的大小和每个成员的偏移量……
grasbueschel 2014年

1
通过实现诸如字节数组之类的结构并执行必要的移位和&/或|操作以读取/写入每个字段的值,可以在不支持硬件的系统上进行不对齐访问。
2014年

1
@ dan04:在许多处理器上,编译器可以生成用于未对齐访问的代码,该代码比使用字节读取和移位序列更有效。相对于要求编译器识别所有不同的程序员可能尝试编写代码以将字节组装成更长的类型的方式,拥有这样的语法将使此类编译器更容易生成高效的代码。
超级猫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.