簡體   English   中英

c中嚴格的別名和數組

[英]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_tuint64_t左值讀取相同的存儲區域,這違反了嚴格的別名。

gcc的快速解決方案是使用-fno-strict-aliasing

一個可靠的解決方法是重寫代碼,使其不包含任何別名沖突。 乍一看,這似乎更難以理解,但是從理論上講,如果您編寫正確的代碼,編譯器將了解發生了什么並生成最佳匯編。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM