簡體   English   中英

使用指向壓縮結構成員的指針時的編譯器警告

[英]Compiler Warning when using Pointers to Packed Structure Members

許多 C/C++ 編譯器(包括 gcc 和 clang)都有一個稱為打包結構的特性。 由於多種原因,它會派上用場,但必須謹慎使用。 一個潛在的陷阱是您使用指向結構成員的指針作為另一個函數的參數。 現在該函數不知道未對齊的指針。 讓我用一些代碼來說明我的意思:

#pragma pack(1)
typedef struct { int x; } uas;
#pragma pack()

void foo(int *f) {
  // some code using the value of *f
}
void bar(uas *b) {
  foo(&(b->x));
}

int在 32 位機器上的對齊通常是 4。如果f不是 4 字節對齊,編譯器現在可能會為foo()生成可能無法工作的代碼。 較舊的 ARM 架構就是這種情況。

現在 struct uas和其中的所有成員的對齊保證為 1。顯然,將b->x的地址傳遞給foo()是一個壞主意。

GCC 和 clang 有一個編譯器警告( -Wcast-align ),例如,通過將char*int*來觸發。 使用指向壓縮結構成員的指針,即使兩者都支持,似乎不會觸發此警告。 我也試過-Wall-Wextra ,但它們甚至不包括-Wcast-align

我的主要問題是 GCC、clang 或任何其他支持打包結構的編譯器是否有由上面的特定示例觸發的警告。 似乎,如果編譯器支持壓縮結構,則此類警告是強制性的。

clang 剛剛針對這個特定問題添加了一個新的-Waddress-of-packed-member警告。 有關詳細信息,請參閱https://reviews.llvm.org/rL278483https://llvm.org/bugs/show_bug.cgi?id=22821 它應該出現在 4.0 版本的 clang 中。

gcc 剛剛在 gcc-9 中添加了相同的警告( -Waddress-of-packed-member )。 使用-Wall時默認啟用

考慮對typedef結構定義進行以下對齊:

#pragma pack(1)
typedef struct { int x; } uas __attribute__ ((aligned (sizeof(uint32_t))));
#pragma pack()

這將通知編譯器確保結構的所有分配都是 4 字節對齊的。

參考在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM