問題タブ [standard-layout]

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.

0 投票する
2 に答える
237 参照

c++ - POD-struct の reinterpret_cast を使用したコード例の理解

いくつかのコードを見つけたので、これを正しく理解していることを確認したいと思います。ユースケースは、値の配列で表されるパックされたイメージです。この例では、3 つの値が 1 つのピクセルを表しています。

私が見つけたコードは次のようになります。

POD と standard layoutを読んでわかるように、Pixel の最初のメンバーしか使用していないため、コード例は有効だと思いますか? 次に、Pixelを次のように置き換えます

未定義の動作になりますか?

編集:私はcudaを使用して、別の例を見つけました:uchar3ポインターへのキャストおよびunsigned charポインター(配列)。uchar3 型の定義は、2 番目のピクセルの定義と同じです。これは、2番目も有効であることを意味しますか?それとも、これは nvcc によってコンパイルされたコードに対してのみ機能しますか? 2 番目の Pixel 定義が有効である場合、その理由は何ですか?

編集:コードが何をしようとしているのかをさらに強調するために、上記のいくつかのフィールドの名前を変更しました:生データの配列があります。私の場合、それはパックされたイメージです。ピクセルとその値にアクセスするための良い方法が必要です。だから私はこのようなことができます:

cuda でこれを使用しているコードを見たことがありますが、動作しましたが、POD について読んだ内容ではカバーされていないように見えるため、常に問題ないかどうかを知りたいです。POD に関する何かを見逃しただけですか、それとも失敗する可能性があるものですか?

編集:次の違いがあります:

POD 型の場合、最初のメンバー変数がオブジェクトと同じアドレスを持っているため、2 番目は合法であるべきだと思いましたか?

編集:回答から得たものは、私が言及したすべてのケースでUBです。進むべき道は、私が望むアクセスを私に与えるランダムアクセスイテレータです。

0 投票する
2 に答える
1651 参照

c++ - プリミティブ型の単一の配列メンバーを持つ標準レイアウト構造体の保証されたメモリ レイアウト

次の単純な構造体を検討してください。

私の質問は:

floatが 32 ビットの IEEE754 浮動小数点数であるプラットフォームを想定すると(それが重要な場合)、 C++ 標準は の予想されるメモリ レイアウトを保証しstruct Aますか? そうでない場合、それは何を保証しますか、および/または保証を実施する方法は何ですか?

予想されるメモリ レイアウトとは、構造体が16*4=64メモリ内のバイトを占有し、連続する各バイトが配列4の 1 つのバイトで占有されることを意味します。つまり、予想されるメモリ レイアウトは、次のテスト パスを意味します。floatdata

(offsetofは標準レイアウトであるため、ここでは有効ですA。以下を参照してください)

これが気になる場合は、テストは実際にはgcc 9 HEAD の wandbox でパスします。このテストが失敗する可能性があるという証拠を提供するプラットフォームとコンパイラの組み合わせに出会ったことがありません。存在する場合は、それらについて学びたいと思います.

なぜ気にするのでしょうか:

  • alignasSSE のような最適化には、特定のメモリ レイアウト (および標準指定子を使用して処理できるため、この質問では無視するアライメント) が必要です。
  • このような構造体のシリアル化は、単に便利でポータブルなwrite_bytes(&x, sizeof(A)).
  • 一部の API (たとえば、OpenGL、具体的にはglUniformMatrix4fv など) は、この正確なメモリ レイアウトを想定しています。もちろん、ポインタをdata配列に渡してこのタイプの単一のオブジェクトを渡すこともできますが、これらのシーケンス (たとえば、マトリックス タイプの頂点属性をアップロードするため) には、特定のメモリ レイアウトが必要です。

実際に保証されるもの:

これらは、私の知る限り、次のことから期待できますstruct A

  • スタンダードなレイアウトです
  • 標準レイアウトであるため、ポインタは最初のデータ メンバ (おそらく ?) へのポインタにAなる可能性があります。つまり、最初のメンバのにパディングはありません。reinterpret_castdata[0]

(私の知る限り)標準によって提供されていない残りの2つの保証は次のとおりです。

  • プリミティブ型の配列の要素間にパディングはありません(これは間違っていると確信していますが、確認の参照を見つけることができませんでした)。
  • 内部の配列のにパディングはありません。datastruct A