我正在开发嵌入式系统项目。我的目标是32位(32位地址总线)。如何知道编译器是否执行内存对齐?
我需要知道编译器是否执行内存对齐。
换句话说,如果我声明了以下变量:
uint16_t x = 0xFFFF;
x
将被保存在一个特定条目类似:
Address 0x00000000 -> FFFF0000
或者可以将它保存这样的:
Address 0x00000000 -> 000000FF
Address 0x00000001 -> FF000000
我正在开发嵌入式系统项目。我的目标是32位(32位地址总线)。如何知道编译器是否执行内存对齐?
我需要知道编译器是否执行内存对齐。
换句话说,如果我声明了以下变量:
uint16_t x = 0xFFFF;
x
将被保存在一个特定条目类似:
Address 0x00000000 -> FFFF0000
或者可以将它保存这样的:
Address 0x00000000 -> 000000FF
Address 0x00000001 -> FF000000
当然,你的编译器总是会做出明智的选择e目标架构。
通常,它会将数据类型与该数据类型的“自然”地址对齐。这不会错误地对齐变量,以便访问它会导致一些错误或具有灾难性的性能。
对于你的特殊情况,如果x
是一个局部变量,它可能会在一个寄存器或堆栈中,而不是一个事先已知的绝对地址。大多数平台都有堆栈对齐的规则可能会发挥作用(即当进入某个函数时,堆栈可能始终与某些2的幂对齐)。如果它不是本地自动的,则上述内容将适用,即编译器将以自然和“良好”的方式对齐变量。
如果x是一个静态或全局的? –
如果x是静态的或全局的(全局无论如何都是静态的)取决于你声明它的方式和位置! –
无论是在'.data' /''.bss'还是在堆栈中分配,编译器仍然需要做相同的基本对齐考虑。这个答案的意思是,除此之外还有其他一些考虑因素,具体取决于堆栈的处理方式([有关堆栈处理的更多信息](http://en.wikipedia.org/wiki/Call_stack))。 – Lundin
可能是一个简单的方法来检查:
uint8_t *pChar;
uint16_t x = 0xFF;
(uint8_t *)pChar = (uint8_t *)&x;
,然后打印:
*pChar
和*(pChar + 1)
这也有利于检查Endian的模式下,CPU英寸
如果您使用GCC编译器(可能作为交叉编译器定位您的系统),您可以使用__alignof__
keyword(它是GCC扩展)。您可能还需要使用packed
variable attribute
由于Lundin明智评论,最新C11标准给你_Alignof
关键字和_Alignas
符。
因此,值得使用最近的编译器。
或者只是使用C11编译器(例如GCC 4.9.x),然后使用标准的'_Alignof'关键字。 – Lundin
我只相信编译器完成其工作...否则我想你可以做一些“hackish的”东西发现:
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
int main()
{
uint16_t x = 0xFFFF;
uintptr_t align = (uintptr_t)&x % sizeof(uint16_t);
if(align != 0) // aint gonna happen
{
printf("Scandal! Variable incorrectly aligned!\n");
}
align = (uintptr_t)&x % sizeof(uintptr_t);
if(align != 0) // might very well happen, not an issue
{
printf("Variable not aligned at an address which is a multiple of the CPU alignment\n");
printf("At address %p, \"optimal\" %p", &x, (uint8_t*)&x - (uint8_t*)align);
}
return 0;
}
如果使用的是C11,你可以强制编译器使用不同的对齐方式。如果上面的代码更改为
_Alignas(uintptr_t) uint16_t x = 0xFFFF;
那么你不应该得到任何印刷,因为它强制在同一对准被分配为是地址总线宽度的变量。为什么你想这样做,我不知道,因为编译器知道如何做比这些程序员更好的事情。
1.它会给你什么? 2.试着去看看你是否有这种感觉,如果你是全部定下来的话。 – Eregrith
阅读编译器的手册。通常,编译器提供了在静态分配的变量上指定显式对齐控制的方法,如'#pragma DATA_ALIGN'。 – user3528438
此外,如果您正在进行微控制器编程,您通常会拥有一个“映射文件”的好处,它可以完全显示如何分配所有内容以及在什么地址。 – Lundin