[英]Force struct member alignment (with IAR compiler)
考慮這個 typedef:
#pragma pack(4)
typedef struct
{
uint8 dataArea0[11];
uint8 dataArea1[12];
uint8 dataArea2[13];
uint8 dataArea3[14];
} myStruct;
我有一些我想從其他庫中使用的非 2^n 大小的 arrays。 從這些庫中,這些數據區域可以轉換為例如結構或我需要的任何東西。 當這些結構成員之一位於非 4 字節對齊的地址並且包含對其地址 alignment 不滿意的數據類型時,就會出現問題。
因此,我想用 pack pragma 強制 alignment ,但這沒有幫助(至少在 IAR 編譯器中——來自手冊:使用這個 pragma 指令來指定結構和聯合成員的最大 alignment。 )。 我也嘗試使用 data_alignment 雜注,但這似乎是針對變量而不是結構成員。
有誰知道一個很好的編譯器技巧來強制結構成員的 alignment ?
有興趣的人可以快速鏈接到編譯器手冊: IAR AVR32 Compiler Ref
編輯:我最終使用它作為替代
#define ROUND_UP_NEXT_FOUR(x) ((x + 3) & ~0x03)
typedef struct
{
uint8 dataArea0[ROUND_UP_NEXT_FOUR(11)];
uint8 dataArea1[ROUND_UP_NEXT_FOUR(12)];
uint8 dataArea2[ROUND_UP_NEXT_FOUR(13)];
uint8 dataArea3[ROUND_UP_NEXT_FOUR(14)];
} myStruct;
通過這種方式,我確信填充將發生在 4 對齊的地址。
編輯2:
go錯誤的示例:
struct otherStruct
{
uint16 dataBuf0;
uint32 dataBuf1;
uint32 dataBuf2;
uint32 dataBuf3;
uint32 dataBuf4[10];
};
myStruct* myStructInstance = 0x00000000; //some address
//address of this is 0x0B
struct otherStruct* oS = (struct otherStruct*) myStructInstance.dataArea1;
//we assign to a 2 byte variable that is
//located at address that is not 2 byte aligned -> error!
os->dataBuf0 = 10;
在這種情況下,我們會收到運行時錯誤(最壞(或最好?)情況,崩潰)。
不幸的是,IAR AVR32 編譯器不支持_Alignas
關鍵字。 但是,當啟用 IAR 語言擴展時,它支持匿名聯合,這可用於強制結構的各個字段的 alignment。 訣竅是聯合的 alignment 是其任何字段中最嚴格(最大)的 alignment。 因此,通過包裝每個字段dataArea?
在具有 32 位 alignment 的虛擬字段的匿名聯合中,可以強制每個dataArea?
字段為 32 位。 一個例子如下所示。 它包括原始匿名聯合聲明以及宏魔術以在字段數量很大時簡化聲明。
#include <stdint.h>
#define GLUE_B(x,y) x##y
#define GLUE(x,y) GLUE_B(x,y)
#define ALIGNED(FIELD, ALIGN_TYPE) union { FIELD; ALIGN_TYPE GLUE(a,__LINE__); }
#define ALIGNED32(FIELD) ALIGNED(FIELD, uint32_t)
typedef struct
{
ALIGNED(uint8_t dataArea0[11], uint32_t);
ALIGNED32(uint8_t dataArea1[12]);
union { uint8_t dataArea2[13]; uint32_t a2;};
union { uint8_t dataArea3[12]; uint32_t a3;};
} myStruct;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.