我正在为 Microblaze 处理器使用 GCC 编译器。
最近遇到了变量对齐的问题。我注意到有时编译器将静态变量分配给未对齐的地址(地址不能被 4 整除),因此如果我将未对齐变量的指针发送到任何函数,我会得到未对齐访问硬件异常。
我有两个关于该主题的问题:
__attribute__((aligned(4)))
但这很不舒服,因为我需要为我拥有的每个静态变量定义它,这是没有意义的。
谢谢。
最佳答案
AFAIK 没有办法告诉 GCC 你想对整个编译单元强制执行某种对齐。那就是没有像“alignment_unit 4”这样的编译器标志。
我不是这个主题的专家(尤其不是 Microblaze 软核),但我对 GCC 进行了一些实验,针对我 PC 的 Intel x64 CPU 和针对 ARM Cortex-M4 微 Controller 的 IAR C。
SETUP 1:全局(文件级)变量
static uint64_t a = 0;
static uint8_t b = 0;
static uint16_t c = 0;
static uint16_t d = 0;
static uint8_t e = 0;
int main()
{
printf("&a = %u\n", &a);
printf("&b = %u\n", &b);
printf("&c = %u\n", &c);
printf("&d = %u\n", &d);
printf("&e = %u\n", &e);
return 0;
}
SETUP 2 : 本地(函数级)变量
void some_func()
{
uint64_t a = 0;
uint8_t b = 0;
uint16_t c = 0;
uint16_t d = 0;
uint8_t e = 0;
printf("&a = %u\n", &a);
printf("&b = %u\n", &b);
printf("&c = %u\n", &c);
printf("&d = %u\n", &d);
printf("&e = %u\n", &e);
}
int main()
{
some_func();
return 0;
}
我关闭了所有优化。
两种设置都不会导致 4 字节(或 PC 为 8 字节)对齐的变量地址。编译器/平台组合都是这种情况。
我能想到的唯一可能的解决方案(尽管可能不优雅)是为自定义类型创建一个 header 并将以下 typedef 放在那里:
typedef __attribute__((aligned(4))) uint64_t ui64_aligned;
typedef __attribute__((aligned(4))) uint32_t ui32_aligned;
typedef __attribute__((aligned(4))) uint16_t ui16_aligned;
typedef __attribute__((aligned(4))) uint8_t ui8_aligned;
然后只需在需要时使用“对齐类型”。这样,您将同时拥有“自定义对齐”和“自动对齐”类型,并且您也不会损害代码可读性(太多......)。
我知道这不是您正在寻找的解决方案,但这至少有效(就我的测试而言)。
关于c - GCC 变量对齐问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40862244/