JIS X 3010 : 2003 6.7.3.1 restrict の形式的定義
を確認しましたが、この内容がどういう理論なのか、理解できませんでした。
同じブロック内で restrict 修飾のあるポインタが同じオブジェクトを指さないことを保証している、といったふわっとした理解しかできていません。
どなたか、分かりやすく解説いただけないでしょうか。
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
「保証している」というより「プログラマが保証する」という意味です。
メモリ領域が重なる可能性があることで最適化が制約される場合があり、重なる可能性がないことをプログラマはわかっているから積極的に最適化してよいというヒントとして restrict
は機能します。
また、関数の仮引数に restrict
が付いていれば領域が重なる可能性があるものを渡してはいけないというコメントのような役割にもなると言えるでしょう。 例えば memcpy
は void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
と宣言されているのでこの型を見るだけで範囲が重なってはならないことが一目瞭然なわけです。
投稿2020/09/13 16:06
総合スコア5684
0
これは、コンパイラが、より最適化したコードを出力できるようにするための機能です。
例えば「メモリバッファをコピーする関数を作る」という要件を実装する必要があった時に、この要件だけでは領域が重なっているかどうかがわからないためmemmove()
を使う必要があります。
でも、この要件に加えて、渡される2つのバッファのポインタにrestrictが付いていれば、お互いの指すバッファが重ならない(自身のポインタ経由以外では更新されないので、相手のポインタで更新されることはない、すなわち領域が重なっていない)ことがわかるので、memcpy()
が利用できます。こちらの方が一般的には高速です。
このような判断を、コンパイラ内部でできるようにするためのものです。
ググっただけなので恐縮ですが、こちらの解説はいかがでしょうか。
https://programming-place.net/ppp/contents/c/057.html#restrict
投稿2020/09/13 16:01
総合スコア1038
0
ベストアンサー
そこの例にあるようなvoid f(int n, int * restrict p, int * restrict q)
という宣言だったとすると、「関数f
内でp
を使ってアクセスするメモリ領域と、q
を使ってアクセスするメモリ領域が重なって、なおかつ重なっている部分を更新する」ということが無いことをプログラマがコンパイラに対して保証するために付ける修飾子です。
これを保証することでオブジェクトコードの最適化が行えると言うことでしょう。
この修飾子を付けたのに、上記括弧内のようなことが発生するような引き数を渡すと、動作は未定義と言うことですね。
投稿2020/09/13 17:00
総合スコア85901
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/17 21:18
2020/09/18 09:47
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/17 21:11