問題タブ [strict-aliasing]
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++ - 厳密なポインタエイリアシング:特定の問題に対する解決策はありますか?
厳密なポインタエイリアシングルールに違反したために問題が発生しました。T
テンプレートからの型Int
と、同じサイズの整数型があります(と同様)sizeof
。私のコードは基本的に次のことを行います。
T
コンストラクターを持つことができる任意の(サイズ制限以外の)型であるため、との和集合を作成することはできませT
んInt
。(これはC ++ 0xでのみ許可されており、GCCではまだサポートされていません)。
機能を維持し、厳密なエイリアシングルールに違反しないように上記の擬似コードを書き直す方法はありますか?これはテンプレートであることに注意してください。制御しT
たり、値を設定したりすることはできませんsome_other_t
。割り当てとその後の比較は、テンプレート化されたコード内で行われます。
T
(ちなみに、ビットフィールドが含まれている場合、上記のコードはGCC 4.5で壊れ始めました。)
c++ - 厳密なポインタエイリアシング:「揮発性」ポインタ/参照を介したアクセスは解決策ですか?
特定の問題、自己回答、およびそれに対するコメントに続いて、それが適切な解決策であるか、回避策/ハックであるか、または単に間違っているかを理解したいと思います。
具体的には、コードを書き直しました。
として:
volatile
ポインタへの修飾子付き。
T
私の状況のようint
に扱うことが理にかなっていると仮定しましょう。参照を介したこのアクセスは、volatile
ポインターエイリアシングの問題を解決しますか?
参考までに、仕様から:
[注:オブジェクトの値は実装で検出できない手段によって変更される可能性があるため、volatileは、オブジェクトが関与する積極的な最適化を回避するための実装へのヒントです。詳細なセマンティクスについては、1.9を参照してください。一般に、volatileのセマンティクスは、C++でもCと同じであることが意図されています。— end note]
編集:
上記のコードは、少なくともGCC4.5で私の問題を解決しました。
c++ - boost::bind は厳密なエイリアシング規則に違反していますか?
Boost 1.43 と GCC 4.4.3 を使用して、次のコード
次の警告を生成します
boost/function/function_base.hpp:321: 警告: 型がパニングされたポインターを逆参照すると、厳密なエイリアス規則が破られる
-fno-strict-aliasing を設定せずにこれらの警告を取り除く正しい方法は何ですか?
c - 型のパンニングされたポインターを間接参照すると、厳密なエイリアシング規則に違反します
次のコードを使用して、より大きなプログラムの一部としてファイルからデータを読み取りました。
今、私は使用するように言われ、-O2
次のgcc警告が表示されます:
warning: dereferencing type-punned pointer will break strict-aliasing rules
Googleing私は2つの直交する答えを見つけました:
vs
結局、私は警告を無視したくありません。あなたは何をお勧めします?
【更新】おもちゃの例を実関数に置き換えました。
c++ - Cエイリアシングルールとmemcpy
別の質問に答えている間、私は次の例を考えました:
1行目はエイリアシングルールに違反しています。ただし、2行目は問題ありません。エイリアシングルール。問題は、なぜですか?コンパイラには、memcpyなどの関数に関する特別な組み込み知識がありますか、それともmemcpyをOKにする他のルールがありますか?エイリアシングルールを破ることなく、標準Cでmemcpyのような関数を実装する方法はありますか?
c++ - 厳密なエイリアシングルールに違反しているキャスト
unsigned long *を受け取る関数があり、unsigned int *を受け取る外部ライブラリに渡す必要があります。このプラットフォームでは、unsigned int/longは同じサイズです。
これにより、厳密なエイリアシングルールに違反しているという警告が生成されます。回避策はありますか?
ありがとうございました
編集:明確ではないことをお詫び申し上げます。コードはアトミックアップデートであるため、ライブラリを回って保存することはできません。アセンブリにドロップダウンすることもできますが、C++でこれを実行したいと思います。
c - unsigned char a[4][5]です。a [1] [7]; 未定義動作?
C標準の未定義動作の例の1つは、(J.2)を読み取ります。
—指定された添え字でオブジェクトに明らかにアクセスできる場合でも、配列の添え字が範囲外です(宣言int a[4][5]が与えられた左辺値式a[1][7]のように)(6.5.6)
宣言がからint a[4][5]
に変更された場合でもunsigned char a[4][5]
、アクセスするa[1][7]
と未定義の動作が発生しますか?私の意見ではそうではありませんが、反対する人から聞いたことがあるので、SOの専門家になる他の人がどう思うか見てみたいと思います。
私の推論:
6.2.6.1段落4および6.5段落7の通常の解釈では、オブジェクトの表現
a
はsizeof (unsigned char [4][5])*CHAR_BIT
ビットであり、オブジェクトとオーバーラップする型の配列としてアクセスできunsigned char [20]
ます。a[1]
unsigned char [5]
は左辺値として型を持ちますが、式で([]
演算子のオペランドとして、または同等にの+
演算子のオペランドとして*(a[1]+7)
)使用されると、型のポインターに減衰しますunsigned char *
。の値は、の形式
a[1]
の「表現」のバイトへのポインタでもあります。このように解釈すると、に7を追加することが有効です。a
unsigned char [20]
a[1]
c - このコードに対して厳密なエイリアス警告が生成されないのはなぜですか?
次のコードがあります。
次のコマンドラインでコードをコンパイルしています。
GCC 4.5.0 を使用しています。コンパイラが警告を出力することを期待していました:
しかし、そうではありません。他のケースでは警告を出力することができますが、この場合はなぜ出力されないのか疑問に思っています。これは厳密なエイリアシング規則を破る明らかな例ではありませんか?
c++ - 「タイプパニングされたポインターを逆参照すると、厳密なエイリアス規則が破られます」という警告
enum* を int* にキャストするコードを使用します。このようなもの:
コード (g++ 4.1.2) をコンパイルすると、次の警告メッセージが表示されます。
このメッセージをググったところ、厳密なエイリアシング最適化がオンになっている場合にのみ発生することがわかりました。次の質問があります。
- この警告が表示されたままコードを残した場合、間違ったコードが生成される可能性はありますか?
- この問題を回避する方法はありますか?
- そうでない場合、ソース ファイル内から厳密なエイリアシングをオフにすることは可能ですか (すべてのソース ファイルに対してオフにしたくなく、このソース ファイルに対して別の Makefile ルールを作成したくないため) )?
はい、実際にはこの種のエイリアシングが必要です。
c++ - C++ の単純なストレージ クラスと厳密なエイリアシング
ストレージ用の小さなクラスを持つための次のコードがあります。
storage::get()
gcc 4.4 は、戻ったときに厳密なエイリアシング規則を破っていることを警告しています。
私の知る限り、私はいかなる規則にも違反していません。私は実際に厳密なエイリアシングに違反していますか、それとも gcc はここでうるさくなっていますか?
そして、厳密なエイリアシングを無効にせずに警告を出さないようにする方法はありますか?
ありがとう
編集:
一方、次の実装では警告が表示されません。
編集:
gcc 4.5 以降は警告を発行しません。つまり、これは厳密なエイリアシング ルールの誤解か、gcc 4.4.x のバグであったようです。