语言标准将允许这样的编译指示,但我不知道有任何编译器实现了这样的事情。
在 C 中, 的行为在标准#pragma
的第 6.10.6 节中指定(链接是最新草案):
#pragma pp-tokens opt new-line形式的预处理指令,
其中预处理标记STDC
不立即跟随pragma
在指令中(在任何宏替换之前)导致实现以实现定义的方式运行。该行为可能会导致翻译失败或导致翻译器或生成的程序以不合格的方式运行。任何不被实现识别的编译指示都会被忽略。
所以 a #pragma
can实际上违反了语言规则。
在这种情况下,相关规则是结构成员按照它们声明的顺序排列。6.7.2.1 第 15 段:
在结构对象中,非位域成员和位域所在的单元的地址按声明顺序递增。一个指向结构对象的指针,经过适当的转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。结构对象中可能有未命名的填充,但不是在其开头。
坏消息:C 标准要求结构成员按照声明的顺序排列。第一个成员必须在偏移量 0 处。成员之间可能有任意填充,或者在最后一个之后,但它们不能重新排序。
好消息:该语言允许实现定义一个#pragma
违反上述规则的布局。
坏消息:据我所知,实际上没有任何实现这样做。即使有,也有其他实现没有,所以任何使用这样的代码#pragma
都是不可移植的。(尽管至少如果 的名称#pragma
是唯一的,任何不识别它的编译器都需要忽略它,因此您的代码仍然可以编译。)
那是针对 C 的。C++ 规则#pragma
与 C 规则非常相似。我有理由确定结构布局的 C++ 规则也类似于 C;继承使事情变得更复杂一些。