简体   繁体   English

c中严格的别名和数组

[英]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. 它应该采用一个16位整数数组,在其上加上一个掩码,然后检查它是否包含一个等于0的16位整数(不在跳过位置),如果是,则执行某些操作。 It all works fine till optimalisation -O2 is used (-O1,-Os functioning normally). 在使用优化-O2之前,所有功能都可以正常工作(-O1,-Os正常运行)。

The function is called milions of times, therefore it can not use the 16bit mask and 16bit array because of effectivity. 该功能被称为数百万次,因此由于效果,它不能使用16位掩码和16位数组。 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; 对编译器来说,有什么办法可以说array1和array使用相同的内存位置,因此它不能array[skip]=storage; before evaluating the if statement (I tried union, however with no succes, it did exactly the same as now)? 在评估if语句之前(我尝试并集,但是没有成功,它和现在完全一样)? 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. 是的,通过使用uint16_tuint64_t左值读取相同的存储区域,这违反了严格的别名。

A quick fix for gcc is to use -fno-strict-aliasing . gcc的快速解决方案是使用-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. 乍一看,这似乎更难以理解,但是从理论上讲,如果您编写正确的代码,编译器将了解发生了什么并生成最佳汇编。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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