15

restrictgcc 5 も clang 3.6も、 で呼び出された場合でも、修飾子の制約に違反している場合に警告を発しません-Wall。次のコード フラグメントを検討してください。

extern void f(char *restrict p, char *restrict q);

void g(char *p)
{
    f(p, p);
}

-Wall単純に、違反は静的に判断できると予想し、警告が表示されることを期待していました。どこかでフラグを見逃したのでしょうか、それとも表示されていない警告を出すことに何か問題がありますか?

4

3 に答える 3

3

このrestrictキーワードは、問題のポインターが別名ではないというプログラマーからの明示的な保証です。本質的には、プログラマーが推定される答えを既に提供しているため、コンパイラーはこれらのポインターのエイリアス分析を省略できます。これにより、最適化が向上するだけでなく、コンパイル時間も節約できます。大規模なプログラムでは、分析に非常にコストがかかる可能性があるため、それ自体が大きな問題になる可能性があります。

したがって、あなたの質問に対する答えは、「コードが気にしないように指示しているため、コンパイラは見ていません」だと思います。

于 2015-06-05T00:12:34.073 に答える
3

コードを考えると:

void test(int *restrict a, int *restrict b, int c)
{
  a[0] += b[c];
}

restrict修飾子によって影響を受ける唯一のシナリオは次のとおりa==b+cです。その場合、 のポインターは、 のa関連のないポインターを介してアクセスされるオブジェクトを変更するために使用されますb。が存在しない場合に定義される他のすべてのケースでは、restrictを介してアクセスされるオブジェクトaは も介してアクセスされbず、その逆もありません。

渡された関数restrict- 修飾されたポインター引数が関連する規則に違反してそれらを使用したことを確認できるコンパイラーは、そのような違反を警告するのに役立ちますが、関数を確認できないコンパイラーは、どの組み合わせかを知る方法がありません。の引数が有効または無効になります。

于 2017-05-17T20:34:02.507 に答える