c99 __restrict和编译器优化

DrT*_*d13 6 c compiler-construction optimization c99 restrict-qualifier

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;
}
Run Code Online (Sandbox Code Playgroud)

似乎对于英特尔编译器的版本11.1和gcc的版本4.6,编译器为最后4个语句中的每一个重新加载my_s1_ptr-> field1.我对__restrict的理解会告诉我,最后3次加载应该是多余的,可以消除.是的,我知道代码很奇怪,但有一个原因是这样的结构.我希望能够让编译器消除冗余负载.知道如何说服它这样做吗?

Bo *_*son 3

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

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

如果编译器无法证明您的赋值永远不会改变指向的内容,则每次都必须重新加载指针。例如,它如何判断 thatvoid* field1不是指向自身?


如果没有所有的演员阵容,这样的事情难道不会起作用吗?

int* p = my_s1.field1;
p[1] = 0;
p[2] = 1;
p[3] = 2;
p[4] = 3;
Run Code Online (Sandbox Code Playgroud)

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