c99\uuu限制与编译器优化
对于Intel编译器的11.1版和gcc的4.6版,编译器似乎会为最后4条语句中的每一条重新加载my_s1_ptr->field1。我对限制的理解是,最后3个负载应该是冗余的,可以消除。是的,我知道代码很奇怪,但它是这样构造的是有原因的。我只是希望能够让编译器消除冗余负载。你知道如何说服它这样做吗?c99\uuu限制与编译器优化,c,optimization,compiler-construction,c99,restrict-qualifier,C,Optimization,Compiler Construction,C99,Restrict Qualifier,对于Intel编译器的11.1版和gcc的4.6版,编译器似乎会为最后4条语句中的每一条重新加载my_s1_ptr->field1。我对限制的理解是,最后3个负载应该是冗余的,可以消除。是的,我知道代码很奇怪,但它是这样构造的是有原因的。我只是希望能够让编译器消除冗余负载。你知道如何说服它这样做吗?s1*\u restrict意味着这是指向特定s1的唯一指针,因此该类型没有别名。这并不意味着其他指针类型(如void*、int*或char*)将没有别名 使用char*对编译器来说尤其麻烦,因为ch
s1*\u restrict
意味着这是指向特定s1
的唯一指针,因此该类型没有别名。这并不意味着其他指针类型(如void*
、int*
或char*
)将没有别名
使用
char*
对编译器来说尤其麻烦,因为char*
被特别允许用于访问其他类型的字节。(char
也表示字节,可用于访问其他类型的底层内存)
如果编译器无法证明您的赋值永远不会更改指向的内容,那么每次都必须重新加载指针。例如,它如何判断void*field1
没有指向自身
如果没有所有的演员,像这样的作品不是很好吗
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;
}
假设
int
是4个字节,而field1
实际上指向这些字节的数组。您是否使用优化编译?为什么你要使用\u restrict
而不是restrict
,这是一个C99关键字?我确实进行了优化编译,\u restrict vs restrict没有任何区别。我只是尝试了几个变量,用指向字段的指针代替指向结构的指针,它没有改变任何东西。在实际代码中,可能有多个指针指向field1指向的对象,因此向field1添加restrict是无效的(但即使我尝试了,也没有消除负载)。如果我将field1复制到一个restrict局部变量指针,那么冗余负载将被消除,但正如我所说的,这违反了程序的语义。AFAIK,restrict
并不总是优化。它“可能允许编译器”执行优化。执行这些优化不需要编译器。不管怎样,我还是觉得奇怪,你的例子不正确吗?字段1在取消引用时不会指向任何内容。。。其次,由于my_s1_ptr->field1没有限制,它重新加载指针不是很正常吗,还是说它重新加载my_s1_ptr?“char
也意味着byte”->编译器必须注意任何char
,或者只是无符号char
?(不确定,这就是我问的原因。:P)我们通常使用无符号字符
,因为这样我们就知道有符号,但是纯字符
可能是相同的,也可以用于访问内存(无论是否实际有符号)。“s1*\u restrict
意味着这是指向特定s1
的唯一指针。”:我不知道\u restrict
,但C99的restrict
就不是这样,例如在void*memcpy中(void*restrict s1,const void*restrict s2,size\n)代码>。第6.7.3.1节定义了基于对象的指针表达式的概念,没有指针转换的规定(允许memcpy
按原样进行原型化)。
int* p = my_s1.field1;
p[1] = 0;
p[2] = 1;
p[3] = 2;
p[4] = 3;