問題タブ [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++ - char*変換およびエイリアシングルール
厳密なエイリアシングルールによると:
異なるタイプのオブジェクトへのAchar*
は有効です。しかし、今の問題は、&dの同じアドレスを指しているのでしょうか?同じアドレスを返すというC++標準による保証は何ですか?
c - 型がパニングされたポインターを逆参照するための修正により、strict-aliasing が壊れます
GCC を使用して特定のプログラムをコンパイルするときの 2 つの警告を修正しようとしています。警告は次のとおりです。
警告: 型がパニングされたポインターを逆参照すると、strict-aliasing ルールが破られます [-Wstrict-aliasing]
そして、2人の犯人は次のとおりです。
と
着信_bufと発信_bufは次のように定義されます。
これは、私が調べてきたその警告の他の例とは微妙に異なっているようです。厳密なエイリアスチェックを無効にするよりも、問題を修正したいと思います。
ユニオンを使用するための多くの提案がありました - この場合に適したユニオンは何でしょうか?
c - 組み込みシステムで型のパンニングを安全に実行する方法
私たちのチームは現在、GCC 4.5.1のカスタマイズされたバージョンを使用して、古いアーキテクチャからARMCortexM3プラットフォームに基づく新しい製品に移植されたコードを使用しています。通信リンクからデータを読み取り、生のバイト配列を構造体にキャストしてデータをクリーンに解析しようとしています。ポインターを構造体にキャストして逆参照した後、「型のパンニングされたポインターを逆参照すると、厳密なエイリアシング規則に違反します」という警告が表示されます。
いくつかの調査の結果、char配列には整列規則がなく、構造体は単語整列する必要があるため、ポインターをキャストすると未定義の動作(悪いこと)が発生することに気付きました。私たちが試みていることを行うためのより良い方法があるかどうか疑問に思います。
GCCの「属性((aligned(4)))」を使用して、char配列を明示的にワードアラインできることはわかっています。これによりコードが「より安全」になると思いますが、警告によってビルドが乱雑になるため、この状況が再び発生した場合に備えて警告を無効にしたくありません。私たちが望んでいるのは、私たちが試みていることを安全に行う方法です。それでも、後で別の場所で安全でないことをしようとしても、それは私たちに知らせてくれます。これは組み込みシステムであるため、RAMの使用量とフラッシュの使用量はある程度重要です。
移植性(コンパイラーとアーキテクチャー)は大きな問題ではありません。これは1つの製品にのみ当てはまります。ただし、ポータブルソリューションが存在する場合は、それが推奨されます。
これが私たちが現在行っていることの(非常に単純化された)例です:
c++ - Cキャストを介して構造体の最初のフィールドにアクセスすると、厳密なエイリアシングに違反しますか?
このコードは厳密なエイリアシングに違反していますか?
より抽象的に言えば、プリミティブな読み取り/書き込み操作が正しい型である限り、異なる型間でキャストすることは合法ですか?
c++ - エイリアシングルールを破ることはできますか?
この警告が表示されます。定義された動作が欲しいのですが、このコードをそのままにしておきたいです。エイリアシングルールに違反するのはいつですか?
警告:型のパンニングされたポインターを間接参照すると、厳密なエイリアスのルールが破られます[-Wstrict-aliasing]
文字列はPODである私自身の文字列です。このコードはCから呼び出されます。Sはintである可能性があります。文字列はほとんどですstruct String { RealString*s; }
が、テンプレート化されたヘルパー関数です。Stringがポッドであり、4バイトであり、intが4バイトであることを確認するために、静的アサーションを実行します。また、すべてのポインターが>=NotAPtrであるかどうかをチェックするアサーションを作成しました。それは私の新しい/mallocオーバーロードにあります。あなたが提案するなら、私はそのアサーションを文字列に入れるかもしれません
私が従うルール(主に文字列はポッドであり、常にintと同じサイズです)を考慮すると、エイリアシングルールに違反しても問題ありませんか?これは、それを正しく破っている数少ない回数の1つですか?
linux - 打ちのめされた警告
私はこのようなことをしたい:
しかし、gcc は次の警告を出しています:
逆参照されたポインターをポインター変数に割り当てていなかったので、私が行っていたことが厳密なエイリアシングの目的での逆参照としてカウントされたとは思いませんでした。
私は試した:
違いはありませんでした。
Redhat Linux バージョン 2.6.32-220、gcc バージョン = 4.4.6
厳密なエイリアシング警告を使用する方法はありますが、それでもこのようなことを行いますか?
ありがとう!
編集
これらは機能しません:
これは機能します:
皆さんはこれについてどう思いますか?
c++ - 厳密なエイリアシングとアライメント
n3242以降の3.10/10および3.11を明示的に考慮して、ISO-C ++ 11に準拠し、任意のPODタイプ間でエイリアスを作成する安全な方法が必要です。ここでは厳密なエイリアシングについて多くの質問がありますが、そのほとんどはC++ではなくCに関するものです。おそらくこのセクションを使用して、ユニオンを使用するCの「ソリューション」を見つけました
要素または非静的データメンバーの中に前述のタイプの1つを含む共用体タイプ
それから私はこれを作りました。
私の質問は、確かに、このプログラムは標準に従って合法ですか?*
警告は一切表示されず、以下を使用してMinGW /GCC4.6.2でコンパイルすると正常に動作します。
*編集:そうでない場合、これを合法的に変更するにはどうすればよいですか?
c++ - uint32_t と uint8_t[4] 未定義の動作の結合?
この回答のコメントでは、次のようなユニオンを使用して整数をバイトに分割することは未定義の動作になると言われています。その場所で提供されているコードは、これと同じではありませんが、類似しています。コードの未定義の動作関連の側面を変更した場合は、メモしてください。
addr = {127, 0, 0, 1};
これまでは、これは次のようなことを行い、対応する ものを取得するための優れたアプローチであると考えていuint32_t
ました。(システムのエンディアンによって異なる結果が生じる可能性があることは認めますが、問題は残ります。)
これは未定義の動作ですか?もしそうなら、なぜですか?( C++ の UB とは、非アクティブな共用体メンバーにアクセスすることを意味するかどうかはわかりません。 )
C99
- この点では、C99 は明らかに C++03 にかなり近いです。
C++03
- 共用体では、いつでもアクティブにできるデータ メンバーは最大 1 つです。つまり、データ メンバーの最大 1 つの値をいつでも共用体に格納できます。C++03、セクション 9.5 (1)、162 ページ
でも
- POD 共用体に共通の初期シーケンスを共有する複数の POD 構造体が含まれる場合 [...]、POD 構造体メンバーのいずれかの共通の初期シーケンスを検査することが許可されます。
- 2 つの POD 構造体 [...] 型は、同じ数の非静的データ メンバーを持ち、対応する非静的データ メンバーが (順番に) レイアウト互換型を持つ場合、レイアウト互換性がありますC++03、セクション 9.2 (14)、 157ページ
- T1 と T2 の 2 つの型が同じ型である場合、T1 と T2 はレイアウト互換型です。C++03、セクション 3.9 (11)、53 ページ
結論
- as
uint8_t[4]
とuint32_t
は同じタイプではありません (厳密なエイリアシングだと思います) (さらに、どちらも POD 構造体/共用体ではありません) 上記は実際に UB ですか?
C++11
- ユニオン型のオブジェクトには一度に 1 つのメンバーしか含めることができないため、集約型にはユニオン型が含まれないことに注意してください。C++11、脚注 46、42 ページ
c++ - Strict aliasing and std::array vs C-style array
When compiling the following code with gcc 4.7 (g++-mp-4.7 (GCC) 4.7.0 built with MacPorts on OS X) I get seemingly contradictory results.
The compiler does not complain when I try to reinterpret and dereference a section of an std::array
as an uint32_t
but it does when using a C-style array.
Example code:
Compiler command is:
Why are they treated differently?
c++ - オブジェクトとして使用されるカプセル化された char 配列は厳密なエイリアシング ルールに違反しますか
次のクラスは厳密なエイリアシング ルールを破ります。
私の標準の読みは、それが正しくないということですが、よくわかりません (私の使用法は、オブジェクトの配列T
+ それらのオブジェクトのいくつかのメタデータを持ちますが、メモリを手動で割り当てずにオブジェクトの構築/分解を制御することです)。標準での配置の例として使用されnew
ます。