問題タブ [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++ - ポインタエイリアス規則の適用(自身のアドレスへのポインタ)
最近、厄介なシュレディンバグに出くわしました。ファイルをフラット メモリ表現にロードしようとしているときに、作成者は次のようなコードを記述していました。
したがって、何が起こっているかというと、コードの最初の行は基本的に にline->data
等しく設定されてい&line->data
ます。が指している値を変更すると、それ自体が指している値line->data
も変更される可能性があるため、これは誤りです。line->data
その時、問題が発生するまでに非常に長い時間がかかったことが不思議に思いました。私の理解では、restrict
(または g++/MSVC で__restrict
)修飾されていない限り、コンパイラはポインターがエイリアスされていると想定する必要があります。したがって、line->data[0]
何かに設定すると、次のアクセスで表示され、line->data[1]
ほぼ確実に無効になります。ただし、デバッガーでは、変更はかなり後になるまで表示されず、書き込みはしばらくの間順調に続きました。
コンパイラ (この場合は MSVC 2013) は、セルフエイリアスが可能であるとは考えていなかったと思います。それは許されますか?
c++ - C ソースと制限修飾子を含むヘッダーを含む Rcpp を使用して R パッケージを構築しますか?
Cで書かれたサードパーティのソースファイルと対応するヘッダー(GSLなどの宣言とインクルードディレクティブを含む)があります。基本的にRcppを使用して関数のラッパーを作成し、これらのソースファイルの周りにRパッケージを構築しようとしています。問題は、これらのファイルに C++ 標準の一部ではない制限修飾子が含まれているため、R CMD INSTALL がパッケージをコンパイルできないことです。.c ファイルには C コンパイラを使用しますが、.h ファイルを C++ コンパイラでコンパイルしようとすると失敗します。ヘッダー ファイル (.cpp ファイルに含まれています) に restrict が見つかると失敗します。
私は C やコンパイラのこと、Rcpp などにあまり詳しくないので、ここで何が最善のアプローチになるのかわかりません。
最も簡単な方法は、おそらく restrict キーワードを削除することです。これは私が現在行っていることです(ヘッダーファイルから制限を削除して.cファイルのままにしておくと、R CMD INSTALLが機能することに驚いています)。ただし、.c および .h ファイルは、R 以外の環境 (実行可能ファイルおよび Python) でも使用されるため、変更しません。すべてのプロジェクトで同一のファイルを使用すると便利です。
また、コンパイルが C++ コンパイラで行われた場合に関数定義から restrict を「削除」するように、空のキーワード restrict を定義しようとしましたが、その作業を行うことができませんでした。私はどこかで同様のアプローチについて読みましたが、明らかにそのようには機能しません。
特定の.hファイルをCコンパイラでコンパイルする必要があることを(Makevarsなどを介して)コンパイラに伝えることができればうまくいきますか?または、これらの関数を呼び出す C++ 関数で問題が発生しますか?
または、これらの関数が C++ ラッパーを介して R から呼び出された場合、キーワード全体がパフォーマンスの面で問題になりますか?
1 つのことは、Rcpp を捨てて、R からの .Call の代わりに .C を使用することですが、ここではパフォーマンスが重要であるため、.Call の方が高速である (そして信頼性が高い) ことを理解しているため、これは良い選択肢ではありません。 )。
最終的に、このパッケージは CRAN への道を見つける可能性があるため、ソリューションはかなり移植可能であることに注意してください。制限のための C++ コンパイラ固有のキーワードがいくつかあるようですが、移植性のためにそれらはオプションではないと思います。
c - 制限されたポインターを別のポインターに割り当て、2 番目のポインターを使用して値を変更することは合法ですか?
次の方法は「制限」契約を尊重しますか?
私の推測ではノーですが、説明が必要です。
c - (const char *restrict, ...) とはどういう意味ですか?
と入力するとprintf
、Xcode は のようなオートコンプリート ヒントを表示しprintf(const char *restrict, ...)
ます。
「const char *restrict」の意味を知りたいですか?
また、Xcode がすべての関数に対してスローするこれらのパラメーターに関する詳細情報はどこにありますか?
c - この関数で制限修飾子を使用できますか?
私は標準を読みましたが、まだ確信が持てません:
関数repl
ではstrchr
、オブジェクトを変更するための別のポインターを取得していました。結果は、最初の文字列が にm
置き換えられた文字列になると思いM
ます。
しかし、これは未定義の動作でしょうか?
はいの場合、ap[cp-ap]='M';
代わりに使用するのは*cp='M';
どうですか?
c - const へのポインターは __restrict と同じ効果がありますか?
定数データがある場合、たとえば次の形式で
double const * const
またdouble const *
これはコンパイラに同じ情報を__restrict
与えますか / 同じ効果がありますか?
私が理解している限り、__restrict
基本的には、指しているデータが別のポインターによって/によって変更されないことを約束します。つまり、const 値へのポインターは、同じような約束をしますね。
__restrict
here は、Visual Studio のキーワードを指します。GCCでも意味は似ていると思います。
c - 構造体内の restrict キーワードの動作
シナリオ:
struct
次のように、すべて宣言された一連のポインターと、restrict
これらのいくつかを引数として取る関数を保持する型があるとstruct
します。
http://www.oracle.com/technetwork/server-storage/solaris10/cc-restrict-139391.htmlによるとinput.ptrXX
、input.ptrYY
非エイリアスとして扱われます。
質問:
コンパイラはinput.ptrXX
andoutput.ptrYY
も非エイリアシングとして扱いますか?