好吧,我明白GCC 4.x警告「解引用類型打斷的指針會打破嚴格別名規則」不是玩笑,我應該清理我的代碼。類型雙引號(GCC) - 在堆棧上增加一個指針參數
我使用GCC 3.x編譯和運行的代碼,如果使用GCC 4.x也會很高興。假設我想讓彙編的代碼儘可能短:函數傳遞一個指針,並且應該向其中寫入一些數據。我原來的代碼直接在堆棧上使用指針(沒有副本),並在那裏增加它(請注意,我不想將增加後的值傳遞給調用者)。你也可以考慮通過寄存器傳遞參數 - 然後任何副本都會被開銷。
所以這是我的「理想」的代碼:
void foo(void *pdataout) {
for (int i=16; i--;)
*(*reinterpret_cast<BYTE**>(&pdataout))++ = 255;
}
我嘗試了一些變種(注意地址,運營商必須在任何類型的鑄造之前應用於「pdataout」):
void foo(void *pdataout) {
BYTE *pdo = reinterpret_cast<BYTE*>(*reinterpret_cast<BYTE**>(&pdataout));
for (int i=16; i--;)
*pdo++ = 255;
}
而且這樣的:
void foo(void *pdataout) {
BYTE *pdo = *reinterpret_cast<BYTE**>(&pdataout);
for (int i=16; i--;)
*pdo++ = 255;
}
沒有取悅GCC 4.x的......這最後一個做 - 但是,它使用參數的副本W¯¯我不喜歡。有沒有辦法做到這一點沒有副本?我不知道如何告訴它的編譯器:-(
void foo(void *pdataout) {
BYTE *pdo = reinterpret_cast<BYTE*>(pdataout);
for (int i=16; i--;)
*pdo++ = 255;
}
我真的不明白爲什麼複製指針(並只增加副本)可以解決任何問題 - 或者代碼仍然危險,但GCC不會檢測到它?首先與上一段代碼片段進行比較。如果有人能解釋我會很高興! – tueftl 2015-02-10 15:06:38
看來問題可以簡化爲'float test = 0.0f;如果(!*(long *)&test){}; long * ptest =(long *)&test; if(!* ptest){};':第一個'&test'行會產生警告,其他行不會。爲什麼?最後2行是否安全? – tueftl 2015-02-10 15:44:38