25

疑問に思っていること: ポインターに制限を追加すると、ポインターが別のポインターのエイリアスではないことをコンパイラーに伝えます。次のような関数があるとします。

// Constructed example
void foo (float* result, const float* a, const float* b, const size_t size)
{
     for (size_t i = 0; i < size; ++i)
     {
         result [i] = a [0] * b [i];
     }
}

resultコンパイラが とオーバーラップする可能性があると想定する必要がある場合aは、毎回 を再フェッチする必要があります。ただし、aとマークされconstているように、コンパイラは a が固定されていると想定することもできるため、一度取得すれば問題ありません。

質問は、このような状況で、restrict を使用するための推奨される方法は何ですか? コンパイラがa毎回再フェッチすることは確かに望ましくありませんが、ここでどのようrestrictに動作するかについての良い情報を見つけることができませんでした.

4

5 に答える 5

16

あなたのポインターは const であり、関数を呼び出す人に、その変数を介して指されているデータに触れないことを伝えます。残念ながら、コンパイラは結果が const ポインターのエイリアスであるかどうかをまだ知りません。非 const ポインターは常に const ポインターとして使用できます。たとえば、多くの関数は const char (つまり文字列) ポインターをパラメーターとして受け取りますが、必要に応じて非 const ポインターを渡すことができます。何かを変更するためのポインター。

基本的に、質問に近づくには、restrict を a と b に追加して、この関数を使用する人が a または b のエイリアスとして結果を渡さないことをコンパイラに「約束」する必要があります。もちろん、あなたがそのような約束をすることができると仮定します.

于 2009-01-19T12:35:52.387 に答える
8

C-99 規格 (ISO/IEC 9899:1999 (E))にはconst * restrict、たとえばセクション 7.8.2.3 にの例があります。

strtoimax および strtoumax 関数

あらすじ

#include <inttypes.h>
intmax_t strtoimax(const char * restrict nptr,
                   char ** restrict endptr, int base);
--- snip ---

したがって、標準const *が冗長である場合にそのような例を提供しないと仮定する* restrictと、それらは実際には冗長ではありません。

于 2011-08-25T16:21:39.673 に答える