我有一个由脚本生成的代码块,代码涉及一些整数常量。我遇到了一个奇怪的问题:其中一个常量等于-2147483648(最小签名int32),Visual Studio生成以下错误:unary minus operator applied to unsigned type, result still unsigned
(这一点特别奇怪,因为我不喜欢在启用错误时已将警告处理起来。)
显然它会看到一个不符合签名类型的整数,使其无符号,然后只应用一元减号。我想结果仍然是正确的,因为它将被转换为int
(这实际上是一个模板参数),但我想避免警告。它只是一个VS功能还是标准有什么可说的呢?
这是违规行:
typedef Proto_Int<-2147483648,32> Typeinfo_77;
答案 0 :(得分:1)
在C ++中,负数存储为带有( - )负号的正数。
这就是为什么min int被定义为,
#define INT_MIN (-2147483647 - 1)
对于int C ++,不理解 2147483648 。所以如果可能的话你也可以把 2147483648 写成( - 2147483647 - 1)
答案 1 :(得分:1)
2147483648
之类的非整数十进制整数文字属于int
,long int
或long long int
类型,特别是可以表示其值的第一类。
在具有32位int
的系统上,2147483648
的类型为long int
或long long int
。
但是您的编译器的警告消息表明它遵循一组不同的规则。在1990 C标准中,未加十进制的十进制整数常量的类型为int
,long int
或unsigned long int
(没有类型long long
)。因此,根据C90规则,2147483648
可能属于unsigned long int
类型。将一元-
运算符应用于它不会更改类型,并且根据无符号算术的规则,结果为2147483648
。
尽管1998,2003和2011 ISO C ++标准中存在这样的文字类型为int
或long int
的规则,但您似乎使用的编译器与任何行为都不一致那些标准。
如果您的模板需要int
,那么unsigned long int
值2147483648
将隐式转换为int
。这种转换的结果(当值超过INT_MAX
时是实现定义的,但很可能是-2147483648
,对于32位二进制补码系统来说是INT_MIN
。
您说C ++源代码是由Python脚本生成的,并且该值不一定是-2147483648
。我认为您只需要添加一个特殊情况,以便将-2147483648
生成为(-2147483647-1)
。 (我建议使用括号;在这种特殊情况下它们不是必需的,但它们是无害的,如果在其他上下文中生成类似的常量,它们可以避免运算符优先级问题。)
请注意,INT_MIN
和INT_MAX
的值可能因不同的实现而有所不同。如果您可能需要针对不同的C ++实现,那么您应该使Python脚本足够智能以处理不同的边界。