gpt4 book ai didi

c - c 中的严格别名和数组

转载 作者:太空宇宙 更新时间:2023-11-04 02:46:16 25 4
gpt4 key购买 nike

我有这样一个函数:

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 位整数数组,对其应用掩码并检查它是否包含不在跳过位置的等于零的 16 位整数,如果是,则执行某些操作。在使用优化 -O2 之前一切正常(-O1,-Os 正常运行)。

该函数被调用了数百万次,因此不能使用 16 位掩码和 16 位数组,因为它是有效的。我想,问题是这段代码违反了严格的别名规则。有什么办法可以告诉编译器,array1 和 array 使用相同的内存位置,因此它不能在评估 if 语句之前省略 array[skip]=storage; (我试过 union ,但没有成功,它和现在完全一样)?或者有没有其他方法可以做到这一点,它不会违反这条规则?

最佳答案

是的,这违反了严格的别名,因为使用 uint16_tuint64_t 左值读取相同的存储区域。

gcc 的快速修复是使用 -fno-strict-aliasing

一个可靠的修复方法是重写代码,使其不包含任何别名违规。乍一看这似乎更神秘,但理论上,如果您编写正确的代码,编译器会看到正在发生的事情并生成最佳汇编。

关于c - c 中的严格别名和数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27077498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com