内存中的x86变量对齐,没有使用C的结构使用C

问题描述:

我在基于x86的CPU上使用C。 有很多文章通过使用structs和#pragma pack指令来解释内存中变量的对齐方式。只要你愿意使用结构,这很好。内存中的x86变量对齐,没有使用C的结构使用C

我正在寻找一种方法来确保内存中的变量对齐(顺序和大小)而不使用结构

有没有办法做到这一点?

#pragma (push) 
**#pragma "anyalignment directive"** 
int a; 
byte b; 
long l; 
#pragma (pop) 
+2

编译器通常负责内存对齐。要做类似你想要的东西,你必须使用特殊的编译器指令来**限定变量队列。它们可以是MSVC的'__declspec'或GCC的'__attribute__'。 –

+1

**你为什么要问?**你应该解释一下! –

+3

[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? –

形式如果你使用GCC或铛,是这样的:

int x __attribute__((aligned(16))); 

https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html

在MSVC:

__declspec(align(16)) int x; 

https://msdn.microsoft.com/en-us/library/83ythb65.aspx

GCC的属性,你可以确保每个变量的这样的定位:

int a __attribute__((aligned(16))); 
byte b __attribute__((aligned(2))); 
long l __attribute__((aligned(32))); 

但是,你为什么会需要呢?编译器可以以它认为合适的方式自由地对声明进行重新排序(与结构成员不同,不需要变量应该位于相邻位置,甚至不在内存中)。另外,用指针越过这些变量的边界将导致未定义的行为。你不能假设b会在a之后出现,并且它们之间会有一定的空隙。

+0

感谢您的输入。我想备份整个内存区域(例如,假设我有一个有大约80个变量的状态机,现在我希望能够拍摄所有这些变量的快照并在更改时间内将状态机恢复到同一状态)。当然,我可以通过它的名字来突破每一个变量,但这在维护/扩展方面并不是很方便。 –

+0

进一步,我可以使用结构,这将适用于x86环境。但是同样的代码也运行在高实时环境(ARM)中,结构在访问其中的成员时会有额外开销的风险(取决于编译器如何处理这个问题)。 –

没有使用struct来强制执行内存分配顺序的标准方法。你将不得不求助于非标准的语法来分配固定地址的变量。

至于对齐方式,可以使用标准C _Alignas关键字强制执行比默认对齐更宽的对齐方式。例如:在Windows

#include <stdio.h> 

// force 16 byte alignment: 
int _Alignas(16) x; 
int _Alignas(16) y; 
int _Alignas(16) z; 

int main (void) 
{ 
    printf("%p\n", (void*)&x); 
    printf("%p\n", (void*)&y); 
    printf("%p\n", (void*)&z); 
    return 0; 
} 

输出为我的海湾合作委员会/ MinGW的是

0000000000407970 
0000000000407990 
0000000000407980 

的16个字节对齐要求是满意的,但我们可以看到,这并不影响分配顺序。

+0

谢谢你的回答。我需要确保所有变量在每次编译时都具有相同的顺序,因此这可能不适合我。 –

+0

@ J.Ens简单:使用一个结构体。 – Lundin

+0

嗨Lundin,是的,一切都很好。但我正在寻找一种方式,而不使用结构... –