简体   繁体   中英

Strict aliasing and arrays in c

I have a function like this:

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])){
        ...
        }
    }

It should take an array of 16bit integers, apply a mask on it and check, whether it contains a 16 bit integer equaling to zero that is not on the skip position and if yes, do something. It all works fine till optimalisation -O2 is used (-O1,-Os functioning normally).

The function is called milions of times, therefore it can not use the 16bit mask and 16bit array because of effectivity. I suppose, the problem is, that this code is breaking the strict-aliasing rule. Is there any way, to say to the compilator, that array1 and array use the same memory location and thus it can't leave out the array[skip]=storage; before evaluating the if statement (I tried union, however with no succes, it did exactly the same as now)? Or is there any other way to do this so, that it wouldn't break this rule?

Yes, this violates strict aliasing by using uint16_t and uint64_t lvalues to read the same region of storage.

A quick fix for gcc is to use -fno-strict-aliasing .

A reliable fix is to rewrite the code to not contain any aliasing violations. This may seem more cryptic at first, but in theory the compiler will see what's going on and generate optimal assembly if you write correct code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM