3

私は従来のプロジェクトの1つにrestrictというキーワードを多用しています。
私はrestrictの根拠を理解していますが、これらの機能の一部に適用した場合、その有用性に疑問を呈します。一意のポインタ型のパラメータでrestrictキーワードが意味をなさないのですか?

は、次の2つの例を取る:

void funcA(int *restrict i){ 
    // ... 
} 

void funcB(int *restrict i, float *restrict f){ 
    // ... 
} 

int main(){ 

    int i = 1; 
    float f = 3.14; 

    funcA(&i); 
    funcB(&i,&f); 
} 

は、1つのrestrictfuncAfuncBのパラメータにタグを付ける可能性がある任意の有効な理由はありますか?

funcAには1つのパラメータしかかかりません。どのように他のものと同じアドレスを持つことができますか?

funcBは、異なるタイプのパラメータをとります。それらが同じアドレスであった場合、それは既に厳密なエイリアシングルールを破っていませんか?

+0

関数がグローバルポインタ/オブジェクトを使用する場合、 'restrict'は値を持つと思います。 – chux

+0

異なるタイプへのポインタに関して、Cは 'char * fgets(char * restrict s、int n、 FILE *ストリームを制限する); 'を指定したため、異なるタイプの' restrict'を持つ値を標準委員会が見ているようです。 – chux

+0

興味深い。 char *は他の型を指すことが許されているので、charは例外ではありません。 –

答えて

5

キーワードrestrictは、最適化を改善するためのインテントの宣言です。これは、与えられたポインタによって指されたオブジェクトが、何か他のものによって指されないことを意味します。(この場合は)関数のパラメータの寿命です。

あなたは関数のコードを表示しないので、静的変数が内部に保持されている可能性があります。 Restrictは、それらの静的変数がパラメータを別名にしないことを保証します。

この例ではグローバル変数が表示されない場合があります。 Restrictは、これらのグローバル変数がパラメータのエイリアスを持たないことを保証します。

実際にはそうです。誰かがちょっと絞り込んで制限に遭ったようです。しかし、ではなく、は "このパラメータとそのパラメータ"を意味します。これは、 "このポインタと他のポインタ"を意味します。機能を考えると

+0

静的変数の内部の良い点。 – chux

+0

これは、ポインタの存続期間、それを介してアクセスされるすべてのオブジェクト、またはそれから派生したポインタに2つの条件の1つが適用されることを意味します。(1)オブジェクトは(ポインタの存続期間中に) 2)オブジェクトは、ポインタまたはそれから派生した他の手段によってアクセスされない(読み取りを含む)。上記の条件が成り立つ場合には、「制限」修飾ポインタは静的または自動持続時間を有するオブジェクトを識別することができるが、その寿命中に変更されない限り、ポインタの存続期間中は「直接」アクセスされない。 – supercat

0

int foo(int *restrict p) 
{ 
    *p = 3; 
    bar(); 
    return *p; 
} 

コンパイラはかなり簡単に見ることができます - のでrestrict修飾子の - bar()*pにアクセスできることにより、正当な方法がないということ。したがってに上記のコードを最適化することができます。

int foo(int *restrict p) 
{ 
    bar(); 
    *p = 3; 
    return 3; 
} 

、それは何もwhasoeverについてbar()を知らなくても、このような最適化を行うことができます。修飾子がない場合、コンパイラは、呼び出し元が、例えば、グローバルintのアドレスがbar()で変更されましたが、restrictのため、コンパイラはそれを心配する必要はありません。

関連する問題