2011-04-19 5 views
3

私は、GCC 4.3.4とクラン2.9と両方の互換性のある方法で指定された属性を使用して構造体を初期化しようとしています。その後、GCCは、それがそのフラグを知らないので、構築することを拒否するので、C++でポータブルな方法で名前付き属性を使用してPOD構造体を初期化できますか?

struct A { 
    unsigned int x; 
}; 

// GCC: error: expected primary-expression before '.' token 
A a = { 
    .x = 0xdeadbeef; 
}; 

// Clang: error: use of GNU old-style field designator extension [-Werror,-Wgnu-designator] 
A a = { 
    x : 0xdeadbeef; 
}; 

私は-Wno-GNU-指示にCXXFLAGS追加することはできません。私は、属性が命名されていない初期化リストを使用することはできません。APIが変更された場合、重大な問題が発生するためです。私が必要

ソリューションは、新しい属性は、彼らが初期化されていない(または好ましくはNULL)しなければならない構造体に表示された場合に事実を保持しつつ、C++標準に準拠する必要があります。構造体はサードパーティーなので、決して変更することはできません。

+0

はに何か問題です。 –

+1

は「私が必要とするソリューションは、標準C++に準拠しなければならない」 - これのどれもまだ++標準Cではありませんので、それは、その後、問題です。 C++ 03は名前付きメンバーによる初期化を持たず、GCC 4.3.4にはC++ 0xがあまりありません。 –

答えて

4

いいえ、あなただけのためにそれらを与える、値を指定することはできません。

A a = { 42 }; 

新しいフィールドは、構造体の最後でを追加している場合、彼らはゼロになります。

+0

悲しいことに、最終的にそれらを追加するという保証はありません。 –

+0

@DavidHolm:これは、適切なバージョン管理システムが必要な理由です。 –

+2

あなたはおそらく機能を書き込むことによって、注文の問題に対処することができ 'make_A(unsigned int型のX){A = {0}。 a.x = x;返す; } '。今、あなたは移植性 'A = make_A(0xdeadbeefが)を書くことができます;'、およびベンダーが前にメンバーを追加する場合は、 'それがゼロに初期化されるX '。最後に 'make_A'にデフォルトパラメータとして追加することができます。したがって、paramsの順序は構造体の順序ではなく、追加された順序になります。しかし、あなたはもはや要求されたようにイニシャライザ式で名前付きメンバを使用していないので、これが受け入れられるかどうかわかりません。 –

2

あなたはこのような何か行うことができます:

#if THIS_IS_GCC 
    #define INIT_ATTR(x,y) x : y; 
#elif THIS_IS_LLVM 
    #define INIT_ATTR(x,y) .x=y; 
#else 
    #error Can't do it :/ 
#endif 

A a = { 
    INIT_ATTR(x,0xdeadbeef) 
}; 

は、しかし、これは本当に標準C++ではありませんが。私は、特定のツールチェーンの2つの特定のバージョンをターゲットとする「ポータブル」としてカウントされていることを確認していないよ

A a; 
a.x = y; 
+1

標準英語でもありません。 –

+0

それはうまくいくはずですが、コードレビューに合格するとは思えません。( –

+1

@DavidHolmクロスコンパイラと互換性があり、標準に準拠していて、他の人がそれを好きになるほどのコードを欲しいと訴えています。あなたの優先順位を注文する必要がありますが、すべての制約が同時に満たされるわけではありません。 –

関連する問題