#pragma align如何工作?

时间:2016-10-09 22:15:59

标签: c pragma

我最近使用'#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)。 - 为什么这是一个预处理器指令?为什么预处理器对此负责? - 当我后来想要引用这些奇怪对齐的变量之一时,幕后发生了什么?它能够知道'变量x是存储器字0x1ABA9的字节3'是什么意思。

编辑:我刚才意识到#pragma指令是针对机器特定的编译器的,因此我的问题的答案可能会受到我工作环境的严重影响。为了给你提供更多信息,我'我正在使用ADI公司的Blackfin +处理器。提供了该芯片的链接here

1 个答案:

答案 0 :(得分:2)

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

Pragma指令是特定于编译器的,因此它们的工作方式取决于编译器。

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

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

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