typedef struct {
void * field1;
} s1;
void func1(void) {
s1 my_s1;
s1 * __restrict my_s1_ptr = &my_s1;
*((int*)((char*)my_s1_ptr->field1 + 4)) = 0;
*((int*)((char*)my_s1_ptr->field1 + 8)) = 1;
*((int*)((char*)my_s1_ptr->field1 + 12)) = 2;
*((int*)((char*)my_s1_ptr->field1 + 16)) = 3;
}
对于 Intel 编译器 11.1 版本和 gcc 4.6 版本,编译器似乎会为最后 4 个语句中的每一个重新加载 my_s1_ptr->field1。 我对 __restrict 的理解表明最后 3 个负载应该是多余的并且可以被消除。 是的,我知道代码很奇怪,但它这样构造是有原因的。 我只是希望能够让编译器消除冗余负载。 知道如何说服它这样做吗?
s1 * __restrict
表示这是指向特定 s1
的唯一指针,因此该类型没有别名。这并不意味着其他指针类型不会有别名,例如 void*
、int*
或 char*
。
使用
char*
对于编译器来说尤其麻烦,因为 char*
被明确允许用于访问其他类型的字节。 (char
也表示字节,可用于访问其他类型的底层内存)。
如果编译器无法证明您的赋值永远不会改变指向的内容,则每次都必须重新加载指针。例如,它如何判断
void* field1
没有指向自身?
如果没有所有的演员阵容,这样的东西不会起作用吗?
int* p = my_s1.field1;
p[1] = 0;
p[2] = 1;
p[3] = 2;
p[4] = 3;
假设
int
是 4 个字节,并且 field1
实际上指向这些字节的数组。