#pragma align 如何工作?

How does #pragma align work?

我最近 运行 使用“#pragma align”指令进入嵌入式 C 程序:

/*
 * Audio buffers
 */
#pragma align(4)
static uint32_t RxBuffer1[NUM_AUDIO_SAMPLES];

#pragma align(4)
static uint32_t RxBuffer2[NUM_AUDIO_SAMPLES];

#pragma align(4)
static uint32_t TxBuffer1[NUM_AUDIO_SAMPLES];

#pragma align(4)
static uint32_t TxBuffer2[NUM_AUDIO_SAMPLES];

请注意,此代码摘录是针对 DSP 芯片的,因此它不是 x86-64。

经过一番研究,这似乎是一种将内存中的变量按指定距离对齐的方法。例如,它允许我以 1 字节间隔对齐三个字符变量,而不是将它们放置在典型的内存字宽(例如 4 字节间隔)中。我知道以非单词间隔存储变量会带来一些惩罚。这是因为内存是作为单词检索的,因此如果您只想查看单个字节,则有必要进行移位和屏蔽。

但是,我对“#pragma align”的实际实现方式感到困惑。所以我的主要问题是:它是如何工作的?

我希望得到关于以下项目的一些评论: - “#pragma align”指令是否常见?或者它是否取决于您工作的环境(即 x86 是否存在#pragma align)。 - 为什么这是预处理器指令?为什么预处理器要为此负责? - 当我稍后想引用这些奇怪对齐的变量之一时,幕后发生了什么?能知道'variable x is byte 3 of memory word 0x1ABA9'指的是什么。

编辑:我刚刚意识到#pragma 指令是为特定于机器的编译器设计的,因此我的问题的答案可能在很大程度上受到我工作环境的影响。为了向您提供更多信息,我正在使用 Analog Devices Blackfin+ 处理器。为该芯片提供 link here

虽然它以 # 开头,但 #pragma 不是 预处理器指令,而是由编译器处理。

Pragma 指令是特定于编译器的,因此它们具体如何工作取决于编译器。

这不是标准的:C++11 使用 alignas 说明符来实现这一点。较旧的编译器有替代方案(例如 MSVC _declspec(align(4))),并继续支持它们以与现有源代码兼容。

就是说,编译器之间支持的 #pragma align 相当相似,并且完全按照您描述的方式工作,分别指定数据类型和结构成员的对齐方式。它肯定存在于所有常见的 x86 编译器中。

至于它是如何实现的,那是特定于编译器的。但实际上,编译器必须使用其对齐要求标记类型的内部元数据,以便可以生成正确的机器代码,并正确计算 struct 成员的偏移量,sizeof 和指针算法工作,并且等等。无论如何,每种数据类型都有大小和对齐要求,并且每个成员都有偏移量,因此要更改它们的编译指示只涉及更改前端向后端发送的信息。