2016-10-17 1 views
0

私は構造体を持っていて、は暗黙的な埋め込みをしたくありません。私は-Wpadded警告をオンにC++構造体の末尾にあるパディングについて気にする必要がありますか?私は配列でそれを使用しないことを約束します

#include <cstdint> 
struct foo 
{ 
    uint8_t a; 
    uint32_t b; 
}; 
static_assert(sizeof(foo) == 8, ""); 

> g++ test.cpp -c -Wpadded -std=c++14 
test.cpp:5:12: warning: padding struct to align 'foo::b' [-Wpadded] 
    uint32_t b; 
      ^

> clang++ test.cpp -c -Wpadded -std=c++14 
test.cpp:5:12: warning: padding struct 'foo' with 3 bytes to align 'b' [-Wpadded] 
    uint32_t b; 
     ^
1 warning generated. 

これは素晴らしいことです。それは私が欲しいものです。

ここでメンバーを切り替えます。私は適切な位置合わせの構造体を作るために最後にパディングを気にしません。私はちょうどサイズを最小限に抑えるだろう。

#include <cstdint> 
struct foo 
{ 
    uint32_t b; 
    uint8_t a; 
}; 
static_assert(sizeof(foo) == 5, ""); 

> g++ test.cpp -c -Wpadded -std=c++14 
test.cpp:2:8: warning: padding struct size to alignment boundary [-Wpadded] 
struct foo 
     ^
test.cpp:7:1: error: static assertion failed: 
static_assert(sizeof(foo) == 5, ""); 
^ 

> clang++ test.cpp -c -Wpadded -std=c++14 
test.cpp:2:8: warning: padding size of 'foo' with 3 bytes to alignment boundary [-Wpadded] 
struct foo 
    ^
test.cpp:7:1: error: static_assert failed "" 
static_assert(sizeof(foo) == 5, ""); 
^    ~~~~~~~~~~~~~~~~ 
1 warning and 1 error generated. 

これは私には望ましくないと警告します。

暗黙のパディングが追加されている場合、警告メッセージやコンパイル時エラーが発生することがありますが、末尾に構造体全体を揃えるためのパディングがない場合はどうすればできますか?私は配列でそれを使用することに興味がありません。それとも、危険で不注意なことが許されるのでしょうか?構造体のインスタンスを適切に配置する必要があります。

同じ効果を達成する属性または修飾語はありますか?

+0

gpのバージョンは '#pragma pack(1)'でも構いませんが、これも最初の構造体をパックします –

+0

この埋め込みをしたくない理由は何ですか? –

+0

@ M.M#pragma pack(1)と同等の機能を使用すると、アーキテクチャ上で実行時に「アラインされていないメモリアクセス」トラップが発生します。もし私が回避することができたり、それを修正することができれば、それは素晴らしいかもしれません。 –

答えて

0

あなたはこれを行うことができます。もちろん

static_assert(offsetof(foo, b) == offsetof(foo, a) + sizeof(uint8_t), ""); 

あなたが最初の1の後にメンバーごとに1つのアサートを追加、または例えば、すべてのフィールドを含むように上記を変更する必要がありますcが最後のフィールドの場合:

static_assert(offsetof(foo, c) == sizeof(uint8_t) + sizeof(uint32_t), ""); 

これをより自動化する方法が不思議に思えるかもしれません。

Boost Fusion: validate adapted struct member ordering at compile time

あなたは同じアプローチを使用したい::最後までのすべてのフィールドの合計サイズをしたい場合は、Boost.Fusionを使用することができます...ここで私は尋ねたし、それらの線に沿って答えた質問です最後のフィールドのオフセットが同じかどうかを確認してください。

+0

ブーストフュージョンはヘビー級ですが、私はそれをチェックアウトします... –

+0

@ JetskiSタイプ:ブーストフュージョンは本当に重いですが、しかし、あなたはBOOST_FUSION_ADAPT_STRUCT()を実行し、あなたが望むチェックを実装する単一の.cppファイル内でそれを使うことができます。そして残りのビルドはそれに依存しません。 –

関連する問題