質問

私は少し戸惑いのルールに関する制限のポインタ.そうで助けてくれます。

  1. することは、合法で定義する入れ子に限定ポインタとして

    int* restrict a;
    int* restrict b;
    
    
    a = malloc(sizeof(int));
    
    
    // b = a; <-- assignment here is illegal, needs to happen in child block
    // *b = rand();
    
    
    while(1)
    {
        b = a;  // Is this legal?  Assuming 'b' is not modified outside the while() block
        *b = rand();
    }
    
  2. での法的統制限されたポインタ値として

    int* restrict c;
    int* restrict d;
    
    
    c = malloc(sizeof(int*)*101);
    d = c;
    
    
    for(int i = 0; i < 100; i++)
    {
        *d = i;
        d++;
    }
    
    
    c = d; // c is now set to the 101 element, is this legal assuming d isn't accessed?
    *c = rand();
    

よろしく!アンドリュー

役に立ちましたか?

解決

参考のため、ここではrestrict予選のではなく回旋の定義は(C99 6.7.3.1「制限の正式な定義」から)です。

  

レットDは、通常の宣言であります   の手段を提供する識別子   Aと被検体Pを指定します   制限修飾ポインターをTを入力します。

     

もしDがブロック内部に現れると、   ストレージ・クラスを持ちません。   EXTERN、Bはブロックを示してみましょう。 Dの場合   パラメータのリストに表示されます   関数の宣言   定義は、Bが表してみましょう   関連するブロック。それ以外の場合は、Bを聞かせて   メインのブロック(またはブロックを表します   呼ばれているものは何でも機能の   フリースタンディングでのプログラムの起動   環境)。

     以下では、

、ポインター   式Eは、に基づいていると言われています   物体P場合(一部の配列点で   前へBの実行中   Eの評価)点にPを変更します   配列オブジェクトのコピーにします   それは、以前は変化するであろう指摘しています   「ベース」であることE.ノートの値   との表現のためにのみ定義   ポインタ型ます。

     Bの各実行中に

、Lはであるものとします   P.の場合に基づき、L&持っている任意の左辺値   Lは、の値にアクセスするために使用されます   オブジェクトXは、それが指定していること、およびXは、   また、次に、(任意の手段によって)修飾   次の要件が適用されます。Tはなら   const修飾されません。ほかのすべての   Xの値にアクセスするために使用される左辺値   また、そのアドレスはに基づいていなければなりません   P.すべてのアクセス修正Xはべきこと   以下のために、Pを変更することも考慮されます   この項の目的。 Pの場合   ポインタの値が割り当てられます   他に基づいて式E   制限されたポインタオブジェクトP2、   その後のいずれか、ブロックB2に関連付けられています   B2の実行は、前に開始しなければなら   Bの実行、または   B2の実行前に終了しなければなら   割り当て。これらの場合   要件は、その後、満たされていません   動作は未定義である。

     ここで

そのB手段の実行   の実行の一部   に対応するプログラム   スカラー型のオブジェクトの寿命   自動記憶域期間   Bに関連付けられます。

あなたの最初の質問では、aも「子」ブロック内で、bに割り当てることができないことは、上記の手段の私の読書 - 結果が定義されていません。そのような割り当てはbその「サブブロック」で宣言された場合に行うことができるが、ba同じスコープで宣言されているため、割り当てを行うことができない。

質問2については、cd間の割り当ても(両方の場合において)未定義の動作をもたらす。

(両方の質問のための)標準からの関連するビットである

  Pは、Aの値を割り当てられている場合、

  基づいて、ポインタ表現E   別の制限されたポインタオブジェクトP2、   その後のいずれか、ブロックB2に関連付けられています   B2の実行は、前に開始しなければなら   Bの実行、または   B2の実行前に終了しなければなら   割り当てます。

制限されたポインタが同じブロックに関連付けられているので、ブロックB2は、Bの実行前に開始する、またはB2の割り当て(B、B2が同じブロックであるため)に先立って終了する

は、それが可能ではありません。

は、標準では(私が考える - restrict定義の4つの短い段落の透明性が名前解決規則のC ++と同等のです)このかなり明確になる例を示します:

  

実施例4:

     

間の割り当てを制限するルール   制限付きポインタません   関数呼び出しを区別   そして、同等のネストされたブロック。   唯一の例外、と   「外から内」の割り当ての間   制限付きポインタは、ネストされた中で宣言しました   ブロックは動作を定義しています。

{
    int * restrict p1;
    int * restrict q1;

    p1 = q1; //  undefined behavior

    {
        int * restrict p2 = p1; //  valid
        int * restrict q2 = q1; //  valid
        p1 = q2; //  undefined behavior
        p2 = q2; //  undefined behavior
    }
}

他のヒント

restrict タイプ予選である 表示 のコンパイラの場合にはメモリに対して restrict-有資格のポインタが変更され、他にはないポインタにアクセスも同じ。コンパイラの選択の最適化コードに関 restrict-有資格のポインタにはその結果、誤った行動です。 の責任でのプログラマを制限する指定のポインタを使用していたものを使用します。その他、定義されていない動作が発生することがあります。 (リンク)

これを見ていただきますと、上記の説明と、課題は違法であり、作業中のファイル生産による一部のコンパイラがお休みします。"日本でしかできないのコンパイラ自体を排出するエラーは警告として restrict けることができる限の最適化、を選択することができないなどの場合 volatile.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top