【问题标题】:Alignment of file scope variables文件范围变量的对齐
【发布时间】:2018-05-17 17:08:41
【问题描述】:

我找到了一个来源,作者对变量的对齐和顺序做出了如下假设:

#include <stdio.h>

#pragma pack(push)
#pragma pack(1)
int a;
char b;
char c;
#pragma pack(pop)

void foo(FILE *f)
{
    fwrite(f, &a, 6);
}

我知道在结构的上下文中打包 pragma。但这也可以用于文件范围变量吗?如果这适用于给定的编译器,是否在 C 标准中定义?

【问题讨论】:

  • 除了您的问题之外,我还要问一些其他问题:作者如何确保分配的变量abc 在二进制文件中具有完全相同的顺序? (AFAIK,这不是标准所授予的。)否则,即使 sizeof a + sizeof b + sizeof c 是 6,fwrite(f, &amp;a, 6); 也不是预期的。我至少会在 @ 中捆绑 abc 987654330@。 (不,实际上,我不敢做这种骇人听闻的事情......);-)
  • C 标准识别(定义)#pragma,但该标准没有定义任何打包编译指示。因此,#pragma 的行为取决于编译器。如果编译器不能识别该指令,它必须忽略它——仅此而已。因此,请阅读编译器手册。不要假设它对任何其他编译器都一样(尽管它可能)。当然,C 标准并没有规定它的含义。
  • C 标准不保证此处的排序。事实上,由于这里的 a、b、c 具有外部链接,因此不可能保证它们的顺序,因为另一个翻译单元可以以另一种顺序定义它们。所以在这里打包是非常特定于编译器的,一开始可能是一个糟糕的主意。 (将另一个文件添加到您的编译中,该文件具有与 pragma pack 相同的三个变量,但变量的顺序不同,看看会发生什么)。
  • @Art 变量 a,b,c 在当前翻译单元中定义。如果它们是在其他地方定义的,您将收到有关重复符号的链接器错误。所以我不同意你担心“另一个翻译单元可以按另一个顺序定义它们”。
  • @harper C11 6.2.2:“在构成整个程序的翻译单元和库集合中,具有外部链接的特定标识符的每个声明都表示相同的对象”和“如果声明对象的标识符具有文件范围且没有存储类说明符,它的链接是外部的。"

标签: c visual-studio


【解决方案1】:

我强烈怀疑(但无法证明)发布的代码片段中的#pragma 指令毫无意义。编译器会做一个注释来打包它找到的任何结构声明,但它没有找到任何结构声明。 (这不是我希望编译器警告的那种事情。)

代码工作(如果工作)是偶然的,而不是因为 #pragma 指令确保了它。

特定#pragma 指令的行为取决于编译器,但可以肯定地说,不,打包编译指示不能用于文件范围变量。

不用说,贴出的代码片段中表达的成语是一个可怕的、可怕的想法,即使它看起来有效也不应该依赖。如果它有效,那么它的工作原因是错误的,并且有更好的方法来完成相同的任务。

【讨论】:

  • 不用说,在发布的代码片段中表达的习语是一个可怕的、可怕的想法 IMO 使用“idea”这个词来描述发布的代码,即使带有添加多个“可怕”的实例,太客气了。远远超出“脑放屁”的词浮现在脑海中......
猜你喜欢
  • 1970-01-01
  • 2022-10-07
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2013-05-29
相关资源
最近更新 更多