[英]Strict aliasing and arrays in c
我有一個這樣的功能:
static void doSomething(int16_t array[256], int16_t mask, uint8_t skip){
uint16_t storage = array[skip];
uint64_t* array1=(uint64_t*)(array);
uint64_t mask1 =0;
uint16_t* Lmask=(uint16_t*)&mask1;
Lmask[0]=mask;
Lmask[1]=mask;
Lmask[2]=mask;
Lmask[3]=mask;
int k;
for (k =0 ; k < 64; k++) {
array1[k]&=mask;
array[skip]=storage;
if(hasZero(array1[k])){
...
}
}
它應該采用一個16位整數數組,在其上加上一個掩碼,然后檢查它是否包含一個等於0的16位整數(不在跳過位置),如果是,則執行某些操作。 在使用優化-O2之前,所有功能都可以正常工作(-O1,-Os正常運行)。
該功能被稱為數百萬次,因此由於效果,它不能使用16位掩碼和16位數組。 我想,問題是,這段代碼違反了嚴格混疊規則。 對編譯器來說,有什么辦法可以說array1和array使用相同的內存位置,因此它不能array[skip]=storage;
在評估if語句之前(我嘗試並集,但是沒有成功,它和現在完全一樣)? 還是有其他方法可以做到這一點,而不會違反該規則?
是的,通過使用uint16_t
和uint64_t
左值讀取相同的存儲區域,這違反了嚴格的別名。
gcc的快速解決方案是使用-fno-strict-aliasing
。
一個可靠的解決方法是重寫代碼,使其不包含任何別名沖突。 乍一看,這似乎更難以理解,但是從理論上講,如果您編寫正確的代碼,編譯器將了解發生了什么並生成最佳匯編。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.