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*

a を使用すると、他の型のバイトにアクセスするために a を使用することが明確に許可されているchar*ため、コンパイラにとって特に厄介です。char*(charまた、バイトを意味し、他の型の基になるメモリにアクセスするために使用できます)。

コンパイラが、代入が指し示すものを決して変更しないことを証明できない場合、毎回ポインタをリロードする必要があります。たとえば、それがvoid* field1自分自身を指していないことをどのように判断できますか?


そして、このようなものはすべてのキャストなしで機能しませんか?

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

intanが 4 バイトであり、field1実際にはそれらの配列を指していると仮定します。

于 2012-08-18T09:00:49.180 に答える