我在C中遇到嚴格的別名問題。我正在使用GCC 4.7.1。
實施例1:
當編譯該代碼與-fstrict走樣-Wstrict混疊= 3我得到 「警告:提領類型-punned指針將打破嚴格走樣規則」嚴格的鋸齒規則,假陽性還是假陰性?
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t a[4] = {0x01, 0x23, 0x45, 0x67};
uint32_t b;
b = *(uint32_t *)a;
printf("%x\n", b);
return(0);
}
實施例2:
此代碼給出了-fstrict混疊和-Wstrict走樣= 3或-Wstrict走樣= 2或-Wstrict走樣沒有警告= 1
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t a[4] = {0x01, 0x23, 0x45, 0x67};
uint32_t b;
void *p;
p = a;
b = *(uint32_t *)p;
printf("%x\n", b);
return(0);
}
這兩個示例都能正常工作。
使用聯合也是未定義的行爲,在我的情況下使用memcpy()速度太慢。
因此,第一個例子是安全的(假陽性)還是第二個例子也是不安全的(假陰性)或...?
謝謝。
C99 TC3腳註82明確允許使用聯合進行類型雙擊。 –
很高興知道。謝謝! – LightBit
別名不是你的問題,對齊是。沒有一個'uint8_t' aka'unsigned char'數組是對齊的,這樣你就可以通過指向'uint32_t'的指針讀取它。不要那樣做,你就會陷入困境。 (另一種方法是好的。) –