c - 定义具有特定对齐方式的自动变量的优雅方式
问题描述
我正在使用 ARM 编译器并有一个硬件外围设备(具有直接内存访问),它需要对传递给它的内存缓冲区进行特定对齐(32 字节对齐)。aligned
当缓冲区是全局/静态的并且可以使用编译器支持的属性来定义时,这不是问题。只要需要在本地传递某个函数中定义的缓冲区,即具有自动存储类,就会出现问题。我试图做类似以下的事情:
typedef struct __attribute__((aligned(32)))
{
char bytes[32];
} aligned_t;
_Static_assert(sizeof(aligned_t)==32, "Bad size");
void foo(void)
{
aligned_t alignedArray[NEEDED_SIZE/sizeof(aligned_t)];
//.... use alignedArray
}
这很高兴地编译并在x86编译器上工作。但不是在armcc,这是抱怨:
警告:#1041-D:自动对象的对齐方式不得大于 8
所以这种方法行不通。还有一个,我认为很丑:
void foo(void)
{
char unalignedBuffer[NEEDED_SIZE + 32 - 1];
char pAlignedBuffer = ALIGN_UP_32(unalignedBuffer);
//.... use pAlignedBuffer
}
虽然ALIGN_UP_32
是一个宏,用于返回其中的第一个对齐地址unalignedBuffer
(我猜这里的实现细节并不重要)。
正如我所说,我不喜欢这种方法,想知道是否有更优雅的方法来实现同样的效果?
解决方案
我正在使用 ARM 编译器
您是否也尝试过最近的 GCC(可能配置为交叉编译器),例如 2018 年 11 月的 GCC 8?
ARM ABI 不保证堆栈指针(可能)与 32 字节对齐。
因此,任何自动变量都不会像您想要的那样对齐。
您可以避免它们(并系统地使用适当对齐的堆内存区域)。或者你可以分配比需要更多的东西并对其进行指针运算。
我觉得你char* pAlignedBuffer = ALIGN_UP_32(unalignedBuffer);
的方法很好,我相信优化编译器会生成非常有效的代码。
我不喜欢这种方法,想知道是否有更优雅的方法来实现同样的效果?
我相信你的方法很好,任何其他方式都是等效的。
PS。另一种方法可能是修补您的 GCC 编译器(可能使用插件)以更改堆栈指针的默认对齐方式(因此有效地更改您的ABI和调用约定)。这将花费您数周(或数月)的努力。
推荐阅读
- java - 我想从firebase检索当前用户的ID并将其写入另一个节点,但它只是一直拒绝
- python - Pymongo - 如何将数组添加到列表并读取它
- reactjs - 如何将边框半径添加到 react-konva Image 对象?
- html - 更改 HTML 中的图标大小
- python - 模板中的 Django URL,其中包含 slug
- dataset - 是否可以将内存中的 Jena 数据集存储为三重存储?
- django - is there a way to run my django project server as always reflect the changes?
- c - 无法修复此错误....“初始化使指针从整数而不进行强制转换”
- scala - 如何使用宏在 Dotty 中生成一个类?
- python - Phantom-Evasion OSError: [Errno 2] 没有这样的文件或目录