2016-04-15 12 views
4

GCCの問題を回避するのに問題があります。私はGCC 4.8の下でそれを体験していますが、5.1ではありません。報告されているようです(hereおよび/またはhere)。"要求された位置合わせが整数定数ではありません"

問題の表面を次のように

template <bool B> 
struct S 
{ 
    static const int ALIGN = 16; 
    __attribute__((aligned(ALIGN))) int x; 
}; 

int main(int argc, char* argv[]) 
{ 
    S<true> s1; 
    S<false> s2; 
    return 0; 
} 

そして:

$ g++ test.cxx -o test.exe 
test.cxx:9:41: error: requested alignment is not an integer constant 
    __attribute__((aligned(ALIGN))) int x; 

そのもの種類の重要なクランがGCCと同様に最適化していないので、私はstatic constを保つこと。また、C++ 03も要件です。

これは関連する質問ですが、バグを特定するだけで回避策はありません:Using constant from template base class

問題を回避するにはどうすればよいですか?


ここで問題コンパイラですが、他は3年かそこらのために残った課題の一つを考慮そこにおそらくあります。

$ g++ --version 
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 
Copyright (C) 2013 Free Software Foundation, Inc. 

実際の使用の場合は、もう少し複雑です。マシンがSSE2以上を提供する場合、アラインメントは16です。マシンがSSE4以上を提供する場合、アラインメントは32です。それ以外の場合は、自然アライメントに戻ります。だから、に近いのは、その種:あなたがC++ 03のサポートが必要条件であると言うだけでなく、

template <class W, bool B, unsigned int S> 
struct X 
{ 
    static const int ALIGN = (B ? 16 : sizeof(W)); 
    __attribute__((aligned(ALIGN))) W x[S]; 
}; 

int main(int argc, char* argv[]) 
{ 
    X<int, true, 10> x1; 
    X<long, false, 20> x2; 
    return 0; 
} 
+0

を見つけるのは難しいにつながるアライメントにテンプレートパラメータを作っています可能性? – Yuushi

+0

@Yuushi - テストコードを実行しましたが、うまくいきましたが、テンプレートパラメータを '__attribute__'で直接使用しなければなりませんでした。私はSergeの本質的なミラーリングの提案を使用するつもりだと思います。 – jww

答えて

1

は、私は古き良き定義(はいC-っぽい...)に歩になります。

template <bool B> 
struct S 
{ 
    #define CONST_ALIGN 16 
    static const int ALIGN = CONST_ALIGN; // to allow using it later as S<B>.ALIGN 
    __attribute__((aligned(CONST_ALIGN))) int x; // this uses a litteral int constant 
}; 

もちろん、defineは構造体に対してローカルではなく、次のすべての行でアクセス可能です。しかし、結局それはあまり害を及ぼさず(*)、古いコンパイラがの魔法の寓意(ここでは16)を繰り返さずに理解できるようにします。

(*)後で宣言の近くで使用し、同じファイルであればそれは唯一の可能なタイプミスを隠すことができます:

static const int CONST_ALIGNER = 12; 
... 
int b = CONST_ALIGN; // TYPO should have been CONST_ALIGNER 

これはエラー

+0

その醜いのが、私はそれを取る.... – jww

関連する問題