問題タブ [restrict-qualifier]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 例による制限修飾子の理解
キーワードのrestrict
動作は、C99で6.7.3.1によって定義されています。
Dを、オブジェクトPをタイプTへの制限修飾ポインターとして指定する手段を提供する通常の識別子の宣言とします。
Dがブロック内に表示され、ストレージクラスexternがない場合は、Bがブロックを示します。関数定義のパラメーター宣言のリストにDが表示されている場合は、Bが関連するブロックを示しているとします。それ以外の場合は、Bがメインのブロック(または自立環境でのプログラムの起動時に呼び出される関数のブロック)を示します。
以下では、ポインタ式Eは、(Eの評価前のBの実行のあるシーケンスポイントで)以前にポイントした配列オブジェクトのコピーを指すようにPを変更する場合、オブジェクトPに基づくと言われます。 E.119の値を変更します)'' based''は、ポインタ型の式に対してのみ定義されていることに注意してください。
Bを実行するたびに、LをPに基づく&Lを持つ任意の左辺値とします。Lが指定されたオブジェクトXの値にアクセスするために使用され、Xも(何らかの方法で)変更される場合、次の要件が適用されます。 :Tはconst-qualifiedであってはなりません。Xの値にアクセスするために使用される他のすべての左辺値も、Pに基づくアドレスを持つものとします。Xを変更するすべてのアクセスは、この節の目的のために、Pを変更することも考慮されるものとします。ブロックB2に関連付けられた別の制限付きポインタオブジェクトP2に基づくポインタ式Eの値がPに割り当てられている場合、B2の実行はBの実行の前に開始するか、B2の実行はBの実行の前に終了する必要があります。割り当て。これらの要件が満たされていない場合、動作は未定義です。
他のほとんどの人と同じように、私はこの定義のすべての複雑さを理解するのに苦労しています。この質問への回答として、4番目の段落の各要件について、要件に違反する使用法の一連の良い例を見てみたいと思います。この記事:
「コンパイラが想定するかもしれない...」という観点からルールを提示するのに良い仕事をします。そのパターンを拡張し、コンパイラーが行うことができる仮定と、それらがどのように成り立たないかを、それぞれの例で結び付けることは素晴らしいことです。
c - 制限修飾子を使用するための混乱する適応コード
stpcpy
次のバージョンの関数を、restrict
修飾されたポインターを引数として内部的に使用するように適応させようとしていますが、修飾子を追加するだけで未定義の動作が発生するかどうかはわかりません。
オブジェクトへのアクセスに関する C99 6.7.3.1 の規則が、アクセスされる個々のオブジェクトのみに関係し、配列全体には関係しないと仮定すると、書き込まれた要素は一度だけアクセスされ、書き込みのためだけにアクセスされるため、問題ないと思います。しかし、私はrestrict
この時点で使用することにかなり不快であり、自分の判断だけに頼りたくありません.
c - ポインタ制限の効果がない理由
制限ポインターのgccによるコードの違いはわかりません。
file1
file2
でコンパイルする
file1.sとfile2.sはどちらも同じです.file
が、ファイル名を示す行があります。
これらのコードは両方ともメモリから読み取られ、が指すメモリ位置をに割り当てa
ますb
。私が期待したところ、バージョンはとrestrict
のアドレスを再読み取りせず、とのアドレスはレジスタ内でインクリメントされ、最後にメモリに書き込まれます。a
b
a
b
私がしている何か問題はありますか?それとも、例の選択は大丈夫ですか?
異なるスイッチ、、、、、を試してみましたが、両方-O0
のファイルで 同じ結果が得られました。-O1
-O2
-O3
-Ofast
-fstrict-aliasing
注: gcc --version = gcc(GCC)4.6.3 20120306(Red Hat 4.6.3-2)
EDITコードが変更されました。
c++ - clang ++は__restrictをサポートしていますか?
次のコードはg++4.7.1でコンパイルされますが、clang3.1ではコンパイルされません。
clangはサポートしてい__restrict
ますか?または、特定の構文を使用していますか?
c++ - 関数を呼び出して制限修飾ポインタを渡すのは危険ですか?
次の 2 つの関数を検討してください。
ptr
で宣言されている__restrict
ように、bar
呼び出しはfoo()
危険ですか? 危険とは、 が指すメモリ ゾーンが のメモリ ゾーンとlocalPtr
重複することを意味しptr
ます。それについてのガイドラインは何ですか?
c++ - 参照に__restrictを使用する必要がありますか?
私がコーディングしているプログラムでは、関数宣言の1つは次のようになります。
Microsoft Visual Studio 2010 Expressを使用してコードをコンパイルすると、コンパイラは次のように文句を言います。
警告C4227:時代錯誤が使用されました:参照の修飾子は無視されます
ただし、GCCのドキュメントのこのページには次のように書かれています。
制限付きポインターを許可することに加えて、制限付き参照を指定できます。これは、参照がローカルコンテキストでエイリアス化されていないことを示します。
そして同じページは非常に明確な例を示しています:
MVSCの警告を誤解しましたか?または、すべての参照をポインターに変換して、それが__restrict
適用されるようにする必要がありますか?
c - 制限修飾子を使用するとエラーが発生します
次のプログラムをコンパイルすると、エラーが発生します。
なぜこれらのエラーが発生するのですか?
c - 構造体内のキーワードとポインターを制限する
restrict
次のようなキーワードを使用して:
配列 a と b が重複しないようにコンパイラに指示できます。私は構造を持っているとしましょう:
struct s
2 つのオブジェクトを取る関数を作成します。
a.ip
この場合、とb.ip
が重複しないようにコンパイラに同様に指示するにはどうすればよいですか?
c - __restrictは、厳密なエイリアシングルールを無視することを許可しますか?
charsのバッファーがあり、memcpyの使用を避け、int*変数を介してそれにアクセスしたいとします。
もちろん、これは「a」を出力します。
未定義の動作に遭遇することなくこれを行うことは許可されていますか?
c - tmpfile_sで制限する目的は何ですか?
C11ドラフトから:
C11(n1570)、§K.3.5.1.1
tmpfile_s
関数
errno_t tmpfile_s(FILE * restrict * restrict streamptr);
restrict
ここでの修飾子の目的は何ですか?
他にパラメータがないので、コンパイラはそれがないとstreamptr
エイリアスされていないことを知ることができrestrict
ますね。