Я работаю с компилятором ARM и имею HW-периферию (имеющую прямой доступ к памяти), которая требует специального выравнивания для буферов памяти, передаваемых ему (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
(детали реализации здесь не важны, я думаю).
Как я уже сказал, мне не нравится этот подход, и мне интересно, есть ли более элегантный способ добиться того же?