[英]A type for arbitrary memory in C
這是參考這個問題
接受的答案提到可以使用char
數組對任意內存池進行建模。
但是,對該已接受答案的評論之一指出
沒有分配存儲時間的char數組只能以字符類型作為別名。 換句話說,它不能也不應用作任意內存
這個對嗎? 如果是這樣,那么可以使用什么呢? 我想避免使用alloc
或任何特定的OS調用-所以我對這個問題持對稱態度。
周圍有不同的問題。 首先,如@Magisch的答案所示,相關問題是返回一個懸空指針,導致未定義行為和一般執行錯誤。
第二個與@ ^ *#(此處為檢查)嚴格的別名規則相關。 當您將字符數組用作大緩沖區以從中分配任何類型時,如果您確保正確對齊,則普通編譯器會生成正確的代碼。 畢竟,這是他們必須實現malloc
, realloc
和free
例程的方式。 而且,由於它們是托管環境 (C標准庫)的一部分,因此編譯器開發人員還不足以禁止其使用。
但是C標准在這里更加嚴格。 您應該在此處閱讀我對類似問題的答案,尤其是@EOF對它的評論:
您不能將聲明為char []的對象的一部分打包為其他類型(字符類型除外)的對象,因為它們確實具有聲明的類型...這意味着從技術上講,您不能在純C語言中實現malloc()
問題是對齊。 在具有對齊限制的處理器上, char
數組可能不會從適合於存儲較大對象(例如int
或double
的地址開始。
為了安全起見,您需要確保char
數組對於任何類型都正確對齊。 如果您使用的是C11編譯器,則可以像這樣強制對齊
#include <stddef.h>
#include <stdalign.h>
_Alignas(max_align_t) char buffer[SIZE];
對於較舊的編譯器, __attribute__((aligned(SIZE)))
可能是一個解決方案。 否則,您需要查找強制對齊的#pragma
。
而且,正如在各種注釋/答案中所討論的,您絕對應該使用-fno-strict-aliasing
選項禁用嚴格的別名優化。 如果該選項(或等效選項)不存在,則需要確定依賴於嚴格別名規則的優化級別,並且僅使用較低的優化級別。
我認為他指出的問題是,如果您靜態分配一個char
類型的數組,然后使用像gcc這樣的現代,類似於桌面的C編譯器來編譯您的庫,則無法輕松地將該區域的內容轉換為另一種類型。 因為這樣編譯器將基於指針別名執行優化並將所有事情搞砸,因此請參閱“嚴格的別名規則” 。
只需確保您的編譯器不使用嚴格的別名就可以了。 例如,市場上沒有一個普通的嵌入式系統編譯器可以做到這一點。
使用gcc時,您將編譯為-fno-strict-aliasing
。 始終為可能導致此類問題的代碼啟用警告可能會很有用-Wstrict-aliasing
。
附帶說明一下,將uint8_t
用作泛型類型更有意義,因為與char
不同,它是完全明確的:它沒有簽名,並且大小是眾所周知的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.