2017-01-27 41 views
4

我有一個C函數,它需要一個uint8_t *參數,它必須指向32位對齊的內存。是否有可能在C或C++或任何特定平臺的宏中爲參數添加一些修飾,以便編譯器或鏈接器在構建時拋出錯誤(如果未按需要對齊)?可能強制內存對齊C中的指針參數?

這裏的想法是,我想保護功能,防止其他用戶(或我在6個月內)使用不當。我知道如何調整我想傳遞給它的東西。我想確保沒有人可以通過將錯誤的東西傳遞給它。

基於this answer,我想回答我的問題是「不」,這是不可能在編譯時強制執行這一點,但它似乎是一個非常有用的功能,所以我想我會檢查。我的解決方法是將assert((((size_t)ptr) % 4) == 0);放入函數中,所以至少我可以在調試時在運行時捕獲它。

根據我的經驗,如果您在許多嵌入式平臺上投下未對齊的uint8_t*uint32_t*,結果是不確定的,所以我不想指望最終出現的「正確」結果。另外,這是在實時系統上使用的,所以減速可能是不可接受的。

引用歡迎,如果有的話。

+0

當然不是XY問題?英特爾的錯位訪問幾乎沒有任何損失,而在嚴格的對齊架構上,無論如何都會導致SIGBUS。 – SergeyA

+1

你會如何期待* buld時間的錯誤?這需要編譯器很多,如果我做了'uint8_t * sneaky =(uint8_t *)1; alignmentRequiringFunction(欺騙性);'?或者,如果'偷偷'的價值來自'fgets()'?一個解決方法,至少向調用者表明你期望的是將該參數改爲'uint32_t *',因爲這意味着期望自然對齊。 – unwind

+0

@SergeyA,我不認爲它是[XY](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。我問的是我認爲適當的解決方案。另外,我編輯了你的評論的其餘部分。 –

回答

1

不,我知道C或C++標準中沒有任何東西可以強制指針參數保持適當的值。

爲了獲得存儲器,使用posix_memalign

#include <stdlib.h> 

int posix_memalign(void **memptr, size_t alignment, size_t size); 

說明

posix_memalign()功能必須分配由對準指定的 邊界上對齊size個字節,並應的指針返回到在memptr中分配了內存 。對齊的值應爲sizeof(void *)的兩倍的 的冪。

成功完成後,memptr指向的值應爲 的倍數。

+0

很高興知道,但我在資源受限的嵌入式平臺上,爲實時系統開發裸機固件,因此我們正在靜態聲明所有內容。 –

+0

@ cp.engr如果您將數據聲明爲'uin32_t'而不是'uint8_t'(* de facto *'unsigned char',我懷疑),那麼您的平臺是否強制執行32位對齊? –

+0

是的,但我想在傳遞參數之前抽象出需要投射的東西。 (的確,下層函數將'uint8_t *'轉換爲'uint32_t *'。)我想我也不能吃我的蛋糕並且也吃了嗎? –

0

對於動態分配,請看標準(自C11以來)aligned_alloc

對於靜態分配,我不知道標準方法,所以它會依賴於編譯器。對於gcc例如,請檢查aligned attribute

+0

是'aligned_alloc()'C++的一部分嗎? [這個問題和它的答案](http://stackoverflow.com/questions/29247065/compiler-cant-find-aligned-alloc-function)是幾個月大。就靜態對齊而言,在我所處理的每個平臺上都有一個對齊類型的對齊需求,這樣的類型由任何一個好的編譯器正確對齊,所以在這種情況下,我希望'static uint32_t data [...]; '將在任何平臺所需的對齊上自然對齊。 –

+0

@AndrewHenle:我的答案是針對C的。對於C++,您還有其他選擇,例如['alignas'](http://en.cppreference.com/w/cpp/language/alignas),['aligned_storage']( http://en.cppreference.com/w/cpp/types/aligned_storage)或新的展示位置。回覆。自然對齊 - 這聽起來很合理,但我不確定你可以依賴這種行爲,所以諮詢你的平臺文檔可能是一個好主意。 –