6
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 个负载应该是多余的并且可以被消除。是的,我知道代码很奇怪,但它的结构是这样的。我只是希望能够让编译器消除冗余负载。知道如何说服它这样做吗?

4

1 回答 1

3

s1 * __restrict意味着这是指向特定 的唯一指针s1,因此该类型没有别名。这并不意味着不会有其他指针类型的别名,例如void*,int*char*.

使用 achar*对编译器来说尤其麻烦,因为 achar*特别允许用于访问其他类型的字节。(char也表示字节,可用于访问其他类型的底层内存)。

如果编译器不能证明你的赋值永远不会改变指向的东西,它每次都必须重新加载指针。例如,它怎么知道那void* field1不是指向它自己呢?


如果没有所有演员表,这样的事情不会奏效吗?

int* p = my_s1.field1;
p[1] = 0;
p[2] = 1;
p[3] = 2;
p[4] = 3;

假设 anint是 4 个字节,这field1实际上指向一个数组。

于 2012-08-18T09:00:49.180 回答