使用GCC 4.7.2,为什么会导致严格的别名违规:
#include <stdint.h>
#include "emmintrin.h"
int f(){
int ret = 0;
__m128i vec_zero __attribute__ ((aligned (16))) = _mm_set1_epi32(0);
__m128i vec_one __attribute__ ((aligned (16))) = _mm_set1_epi32(1);
__m128i vec_result __attribute__ ((aligned (16)));
vec_result = _mm_cmpgt_epi32(vec_zero, vec_one);
ret += (((uint32_t*)&vec_result)[0] != 0);
ret += (((uint32_t*)&vec_result)[1] != 0);
return ret;
}
虽然没关系:
#include <stdint.h>
#include "emmintrin.h"
int f(){
int ret = 0;
__m128i vec_zero __attribute__ ((aligned (16))) = _mm_set1_epi32(0);
__m128i vec_one __attribute__ ((aligned (16))) = _mm_set1_epi32(1);
__m128i vec_result __attribute__ ((aligned (16)));
vec_result = _mm_cmpgt_epi32(vec_zero, vec_one);
// ret += (((uint32_t*)&vec_result)[0] != 0);
ret += (((uint32_t*)&vec_result)[1] != 0);
return ret;
}
这只是一个gcc不准确的问题,还是我错过了一些关于严格别名的工作原理。
另外,使用__attribute__((__may_alias__))
是否有一种简单的方法可以解决这个问题,或者我是否也可以将其转换为临时字符*?
答案 0 :(得分:2)
我认为这只是GCC未能解决的问题。它肯定是UB(锯齿违规)。使用__attribute__((__may_alias__))
解决它很容易:
typedef uint32_t __attribute__((__may_alias__)) u32ma;
然后在指针强制转换中使用u32ma
而不是uint32_t
。