任意大小的枚举值

时间:2013-05-14 17:43:49

标签: c++ visual-c++ gcc

我正在编译为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中没有发生截断。海湾合作委员会发生了什么?我怎样才能为MSVC做这个工作?

2 个答案:

答案 0 :(得分:10)

从N3485起,§7.2/ 6:

  

对于其基础类型未固定的枚举,基础类型是可以的整数类型   表示枚举中定义的所有枚举值。如果没有整数类型可以代表所有   枚举值,枚举是不正确的。它是实现定义的,使用整数类型   作为基础类型,除了基础类型不应大于int,除非a的值   枚举器不能在int或unsigned int中。如果枚举器列表为空,则基础类型为   好像枚举有一个值为0的枚举器。

因此,如果MSVC具有必要的long long支持,则 应该使其成为基础类型。看到它没有,你可以尝试一下来哄它。

指定基础类型:

enum tile_flags : unsigned long long {
    ...
};

答案 1 :(得分:0)

如果您需要的条目多于unsigned long long可以获得的条目,请尝试使用结构:

struct tile_flags {
   bool innerFlame : 1;
   bool constricted : 1;
   bool mimicInept : 1;
   bool mimic : 1;
   // etc
};

这使用了一个位域,这通常意味着值将尽可能紧密地打包,虽然它可以使构造比传统的标志号更难,但它是超过sizeof unsigned long long位的最简单选项