2013-12-18 4 views
6

"const restrict"ポインタ引数のエイリアスは正当ですか?

float dot_product(const float* restrict a, const float* restrict b, unsigned n); 

dot_product(x, x, x_len) 

でそれを呼び出すことと同じようにdot_productが宣言されている場合は、C99標準に従って、 "未定義" で?

編集

xx_lenunsignedで、メモリのsizeof(float) * x_lenバイトを指し、当然のポインタです。この質問はエイリアシングに関するものです。

+0

私は引用する標準がありませんが、私はそれが未定義の動作であると想像しなければなりません。他のポインタが同じメモリ位置を参照していないことを明示的にコンパイラに伝え、そのヒントに違反しています。私は 'const'nessがそれに影響を与えるとは思わない。 –

+0

自分自身と矛盾する: 'dot_product'がドットプロダクトの通常の定義である場合、私はそれが*問題ではないと思います。つまり、 'restrict'を違反することは、ポインタに対してのみ読み込み操作を実行しても問題にはなりません。私が問題が起こることを期待すると書いているときだけです。 –

+0

「編集」を削除する必要がありますか?それは冗長なようだ。私は2人の**人が私の質問を誤解していることにショックを受けました。 – MaxB

答えて

6

私はオリジナルのC99(すなわち、ISO9899:1999)テキストを持っていません。私はISO9899:2007:TC3のコピーを持っています。私は、この文書の111ページから取り上げたこのテキストは、C99標準のテキストと非常によく似ていると思います。

6.7.3.1 Formal definition of restrict 

... 

10. EXAMPLE 3 

The function parameter declarations 

    void h(int n, int * restrict p, int * restrict q, int * restrict r) 
    { 
     int i; 
     for (i = 0; i < n; i++) 
      p[i] = q[i] + r[i]; 
    } 

illustrate how an unmodified object can be aliased through two restricted 
pointers. In particular, if a and b are disjoint arrays, a call of the form 
h(100, a, b, b) has defined behavior, because array b is not modified within 
function h. 

これは、エイリアスポインタが読み取り専用アクセスに使用されていれば、動作を定義したと尋ねたフォームの機能を明確に示しているようです。エイリアスポインタのいずれかを使用して書き込むと、未定義の動作が呼び出されます。

-1

はい。定義されていない動作が呼び出されます。 restrictキーワードを使用すると機能は次のように宣言されている場合

float dot_product(const float* restrict a, const float* restrict b, unsigned n); 

コンパイラは別の場所にそのabポイントを想定させ、1つのポインタを更新すると、他のポインタには影響しません。コンパイラではなく、プログラマがの責任を負い、ポインタが同一の場所を指していないことを保証します。

あなたの関数呼び出しは、関数に同じポインタxを渡して

dot_product(x, x, x_len) 

あるので、aまたはbのいずれかを更新することは、他の原因未定義の動作に影響を与えます。

+2

これは 'restrict'ポインタエイリアシングの問題にまったく対処しません。 –

+0

投票者の説明を怠る。 – haccks

+2

これは決して問題に関連していないので、私は下降しました。 @ChrisHayes; –

1

まず、呼び出し自体がUBであるとは思わないが、パラメータとして渡されるポインタがrestrictの仕様と矛盾する方法で使用される場合、UBは関数内でのみ発生する可能性があります。 (UBはコールがあまり意味を持たないので、それが禁止されていれば、UBではなく制約違反になっているはずです)。restrictに関連するUBは、オブジェクトに指さしているものは、「何らかの形で」変更されます。したがって、ベクトルが変更されていない限り、すべて正常です。関数内では、constの資格があるため、これは発生しません。そして、外部のもの(別のスレッドやシグナルハンドラなど)があなたのベクトルを変更すると、あなたは何とかしています。

関連する問題