問題タブ [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++ - 厳密なエイリアシングルールとは何ですか?
Cでの一般的な未定義動作について尋ねるとき、人々は厳密なエイリアシングルールを参照することがあります。
彼らは何を話している?
c - 厳密なポインターエイリアシングに対してchar *が安全なのはいつですか?
char ポインターに適用される厳密なエイリアシング規則を理解しようとしています。
ここでは次のように述べられています。
char* は任意のオブジェクトのエイリアスを参照する可能性があると常に想定されています。
わかりましたので、ソケットコードのコンテキストで、私はこれを行うことができます:
しかし、その後、この声明があります
その逆は正しくありません。char* を char* 以外の任意の型のポインターにキャストし、逆参照することは、通常、厳密なエイリアシング規則に違反しています。
これは、char配列をrecvするときに、メッセージの構造がわかっている場合、構造体へのキャストを再解釈できないことを意味しますか?
基本型が char 配列であり、構造体にキャストしているため、この 2 番目の例は機能しませんか? 厳密にエイリアス化された世界で、この状況をどのように処理しますか?
c - 厳密なエイリアシングとアラインメントを壊さない C のメッセージ ディスパッチ システム
私は、互いにメッセージを送信する複数のタスクで構成される組み込み制御システムを C で作成しています (かなり一般的なイディオムだと思います!)。
- きちんとしている
- ジェネリックです
- 比較的効率的です
- 最も重要なこと:プラットフォームに依存しない (具体的には、厳密なエイリアスやアライメントの問題に違反しない)
概念的には、各メッセージ タイプを個別の構造体定義として表現したいと思います。また、次の関数 (簡略化) を備えたシステムが必要です。
ここで、aqueue_t
はノードのリンク リストで構成され、それぞれにchar buf[MAX_SIZE]
フィールドがあります。私が使用しているシステムにはmalloc()
実装がないため、空きノードのグローバル プールと、次のいずれかが必要になります (認識された問題は太字で示されています)。
sendMsg()
memcpy
空きノードのバッファへの受信メッセージの処理を行います。
私の理解では、呼び出し元が戻り値dequeueMsg()
をさらに処理しない限り、これにはアライメントの問題が発生します。memcpy
- または、呼び出し元 (送信者) が適切な型へのポインターにキャストする次の空きノードの
void *getFreeBuffer()
を返す関数があります。私の理解では、これには途中でアライメントの問題があり、途中でアライメントの問題を回避するためにまだ後が必要です.buf[]
memcpy
dequeueMsg()
- またはノードのバッファ
queue_t
を (eg) として再定義しuint32_t buf[MAX_SIZE]
ます。
私の理解では、これは厳密なエイリアシングに違反しており、プラットフォームに依存しません。
私が見ることができる他の唯一のオプションは、すべてのメッセージタイプの結合を とともに作成することですがchar buf[MAX_SIZE]
、これを「きれい」とは見なしません!
だから私の質問は、どうすればこれを適切に行うことができるのでしょうか?
c - sockaddr_storage をキャストして厳密なエイリアス規則を破らないようにする方法
Beej の Guide to Networking を使用していて、エイリアシングの問題に遭遇しました。彼は、特定の構造体の IPv4 または IPv6 アドレスを返す関数を提案しています。
これにより、GCC は 3 行目のsaに対して厳密なエイリアス エラーを吐き出します。私が理解しているように、この関数を次のように呼び出しているためです。
エイリアシングは、their_addr
変数の型sockaddr_storage
が異なり、別の型の別のポインターが同じメモリを指しているという事実に関係していると思います。
sockaddr_storage
このくっついている、sockaddr_in
、およびを回避する最善の方法はありsockaddr_in6
ますか? これはネットワーキングの分野でよく使われているように思えますが、ベスト プラクティスの良い例が見つかりません。
また、エイリアシングの問題がどこで発生するかを正確に説明できる人がいれば、非常にありがたいです。
c++ - (void*) を識別子の型として使用する
私のプログラムには、すべて一意の識別子を持つ必要がある (同じクラスの) オブジェクトがあります。簡単さとパフォーマンスのために、オブジェクトのアドレスを識別子として使用することにしました。型を単純にするために(void*)
、この識別子の型として を使用します。最後に、次のようなコードがあります。
これは問題なく動作しているように見えますが、gcc から厳密なエイリアスの警告が表示されます。IDがデータ転送に使用された場合、コードが悪いことを理解しています。幸いなことにそうではありませんが、疑問が残ります。エイリアシングの最適化は、生成されるコードに影響を与えるのでしょうか? そして、警告を回避する方法は?
注:(char*)
これは、ユーザーがデータをコピーに使用できることを意味するため、使用するのは気が進まないのですが、それはできません!
c - あるタイプの値を別のタイプに移動すると、厳密なエイリアシングに違反しますか?
uint32_t を使用して任意のタイプのアイテムを移動し、それらを読み戻すことは、厳密なエイリアシング規則に違反しますか? もしそうなら、uint32_ts の配列から任意の型の配列への memcpy への厳密なエイリアシング規則にも違反し、要素を読み戻しますか?
次のコード サンプルは、両方のケースを示しています。
32 ビット プラットフォームに関する私の仮定は無視してください。また、要素が uint32_t と同じサイズでない場合は、それらをパディングして正しい数の uint32_t をコピーすることを知っています。私の質問は、そうすることが厳密なエイリアシングに違反するかどうかに焦点を当てています。
c++ - GCCエラーを理解しようとしています
私は次のコードを持っています:
私がそれを次のようにコンパイルするとき:
次のエラーが発生します。
このエラーはO3で見られますが、O1では見られません。私はcomeauオンラインコンパイラ、MSVC9.0およびiccv11を使用してコードをコンパイルしましたが、すべての場合でコードは問題なくコンパイルされます。
コードは、、、、、イテレータで正常に動作し、std :: std::vector
listの実装に非常に固有のもののようです。std::deque
std::set
char*
int*
この特定のエラー(警告)が何を意味するのか、そしてそれを解決する方法について誰かが洞察を提供してくれることを望んでいました。
注:GCCバージョンは次のとおりです。
c++ - C++ での C99 の厳密なエイリアシング規則 (GCC)
私の知る限り、GCC は C++ で C99 のすべての機能をサポートしています。しかし、C99 の厳密なエイリアシングは C++ コードでどのように処理されるのでしょうか?
関係のない型間での C キャストによるキャストは厳密なエイリアシングセーフではなく、誤ったコードを生成する可能性があることは知っていますが、C++ はどうでしょうか? 厳密なエイリアシングは C++ 標準の一部ではないため (正しいですか?)、GCC はセマンティクス自体を指定する必要があります。
const_cast
関連する型間で計算してstatic_cast
キャストするため、それらは安全ですが、厳密なreinterpret_cast
エイリアシング規則に違反する可能性があります。
これは正しい理解ですか?
c - gcc、strict-aliasing、union によるキャスト
伝えるべき恐ろしい話はありますか?GCC マニュアルは最近、-fstrict-aliasing と共用体を介したポインターのキャストに関する警告を追加しました。
[...]アドレスを取得し、結果のポインターをキャストし、結果を逆参照すると、キャストがユニオン型を使用している場合でも、未定義の動作が発生します[強調が追加されました]。
この未定義の動作を説明する例はありますか?
この質問は、C99標準が何を言っているか、何を言っていないかに関するものではないことに注意してください。今日のgccやその他の既存のコンパイラの実際の機能についてです。
推測にすぎませんが、1 つの潜在的な問題はd
to 3.0 の設定にある可能性があります。d
直接読み取られることはなく、「ある程度互換性のある」ポインターを介して読み取られることもない一時変数であるため、コンパイラーはわざわざそれを設定しない場合があります。そして、f() はスタックからガベージを返します。
私の単純で素朴な試みは失敗します。例えば:
CYGWIN で問題なく動作します:
アセンブラを見ると、gccが完全に最適化t
して いることがわかりますf1()
。事前に計算された答えを単純に保存します。
whilef2()
は 3333333.0 を浮動小数点スタックにプッシュし、戻り値を抽出します。
また、関数もインライン化されています (これが微妙な厳密なエイリアシングのバグの原因になっているようです) が、ここでは関係ありません。(そして、このアセンブラーはそれほど関連性はありませんが、裏付けとなる詳細を追加します。)
また、アドレスを取得することは明らかに間違っていることに注意してください (または、未定義の動作を説明しようとしている場合は正しいです)。たとえば、私たちが知っているように、これは間違っています。
同様に、これが間違っていることはわかっています。
これに関する背景説明については、例を参照してください。
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1422.pdf
http://gcc.gnu.org/ml/gcc/2010-01/msg00013.html
http:// davmac.wordpress.com/2010/02/26/c99-revisited/
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
( = Google でページを検索し、キャッシュされたページを表示)
厳密なエイリアシング規則とは何ですか?
C++ での C99 の厳密なエイリアシング規則 (GCC)
最初のリンク、7 か月前の ISO 会議の議事録草案では、ある参加者がセクション 4.16 で次のように述べています。
ルールが十分に明確であると考える人はいますか? それらを本当に解釈できる人は誰もいません。
その他の注意事項:私のテストは gcc 4.3.4 で、-O2 を使用しました。オプション -O2 および -O3 は、-fstrict-aliasing を意味します。GCC マニュアルの例では、sizeof(double) >= sizeof(int);を想定しています。それらが不平等であっても構いません。
また、cellperformace リンクで Mike Acton が指摘しているように、-Wstrict-aliasing=2
ではなく 、ここの例で=3
は生成されます。warning: dereferencing type-punned pointer might break strict-aliasing rules
c - gcc、厳密なエイリアシング、およびホラーストーリー
gcc-strict-aliasing-and-casting-through-a-unionで、ポインターを介したユニオンのしゃれで問題が発生したかどうかを尋ねました。これまでのところ、答えは「いいえ」のようです。
この質問はもっと広いです:gccと厳密なエイリアシングについてのホラーストーリーはありますか?
背景:c99-strict-aliasing-rules-in-c-gccでのAndreyTの回答からの引用:
「厳密なエイリアシング規則は、[標準化]時代の初めからCおよびC++に存在していた標準の一部に根ざしています。別の型の左辺値を介して1つの型のオブジェクトにアクセスすることを禁止する条項はC89/ 90(6.3 )およびC ++ 98(3.10 / 15)。...すべてのコンパイラがそれを強制したり依存したりすることを望んでいた(またはあえてした)わけではありません。」
さて、gcc-fstrict-aliasing
は現在、そのスイッチを使って大胆にそうしています。そして、これはいくつかの問題を引き起こしました。たとえば、 Mysqlのバグに関する優れた記事http://davmac.wordpress.com/2009/10/と、http://cellperformance.beyond3d.com/articles/2006/06/understandingの同様に優れたディスカッションを参照してください。 -strict-aliasing.html。
その他の関連性の低いリンク:
- fno-strict-aliasingのパフォーマンスへの影響
- 厳密なエイリアシング
- when-is-char-safe-for-strict-pointer-aliasing
- コンパイル時の検出方法-厳密なエイリアシング
繰り返しになりますが、あなた自身のホラーストーリーはありますか?もちろん、によって示されていない問題が優先されます。-Wstrict-aliasing
また、他のCコンパイラも歓迎します。
6月2日追加: Michael Burrの回答の最初のリンクは、確かにホラーストーリーと見なされますが、おそらく少し古いものです(2003年から)。簡単なテストを行いましたが、問題は明らかに解消されました。
ソース:
具体的な苦情は次のとおりです。
一部のユーザーは、[上記の]コードが-fno-strict-aliasingなしでコンパイルされると、書き込みとmemcpyの順序が逆になる(つまり、偽のlenがストリームにmemコピーされる)と不満を漏らしています。
CYGWIN wih-O3でgcc4.3.4を使用してコンパイルされたコード(間違っている場合は修正してください-私のアセンブラーは少し錆びています!):
そして、マイケルの答えの2番目のリンクについては、
gccは通常(常に?)警告を出します。しかし、これに対する有効な解決策(gccの場合)は次を使用することだと思います。
これがgcc-strict-aliasing-and-casting-through-a-unionで問題ないかどうかをSOに尋ねましたが、これまでのところ誰も同意していません。