2

GCC 用に作成されたコードを Visual C++ 2012 でコンパイルしています。次の列挙型で列挙値の切り捨てに関する警告がスローされます (値が int の範囲外であるため)。

enum tile_flags {
   TILE_FLAG_INNER_FLAME= 0x10000000ULL,
    TILE_FLAG_CONSTRICTED= 0x20000000ULL,

    TILE_FLAG_MIMIC_INEPT 0x2000000000ULL
    TILE_FLAG_MIMIC 0x4000000000ULL
    TILE_FLAG_MIMIC_RAVEN 0x6000000000ULL
    TILE_FLAG_MIMIC_MASK 0x6000000000ULL
}

x86 用にコンパイルすると、MSVC は 32 ビットに収まるように列挙値を単純に切り捨てているように見えます。ただし、GCC では切り捨ては発生しません。GCC で何が起こっていますか? そして、これをMSVCで機能させるにはどうすればよいですか?

4

2 に答える 2

10

N3485、§ 7.2/6 から:

基になる型が固定されていない列挙の場合、基になる型は、列挙で定義されたすべての列挙子の値を表すことができる整数型です。すべての列挙子の値を表すことができる整数型がない場合、列挙は不適切な形式です。列挙子の値が int または unsigned int に収まらない場合を除き、基になる型が int より大きくないことを除いて、どの整数型が基になる型として使用されるかは実装定義です。enumerator-list が空の場合、基になる型は、列挙に値 0 の単一の列挙子があるかのようになります。

したがって、MSVC が必要なlong longサポートを持っている場合は、とにかくそれを基になる型にする必要があります。そうではないので、それをなだめるために試すことができることが1つあります。

基になる型を指定します。

enum tile_flags : unsigned long long {
    ...
};
于 2013-05-14T17:44:46.167 に答える