【发布时间】:2014-11-22 12:41:53
【问题描述】:
我有这样的功能:
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 使用相同的内存位置,因此在评估 if 语句之前它不能遗漏array[skip]=storage;(我尝试了联合,但是没有成功,它确实做到了和现在一样)?或者有没有其他方法可以做到这一点,它不会违反这个规则?
【问题讨论】:
-
但是你真的需要氧气吗?
-
不幸的是,整个项目都是使用 -O2 编译的,我无能为力。
-
你的文字是
g++,但你的q被标记为c -
如果使用了
g++,那么它是C++代码,应该为这个站点标记为c++ -
现在我已经在 gcc 上对其进行了测试,它表现出完全相同的行为,因此我将 g++ 部分从正文中删除,以免与它混淆。
标签: c arrays strict-aliasing