此代码是否会在所有理智(例如2-s补码算术)32位机器上打印-1,在LLP64上打印-1(即64位Windows,其中长为32位)和所有64位上的4 gig位Unix OS:es(即在LP64操作系统上):
#include <iostream>
using std::cout;
int main()
{
long li = 0xfffffffful;
cout << "size of li: " << sizeof(li) << ", li: " << li << '\n';
}
通常我使用明确定义的相关变量大小,并使用std :: numeric_limits而不是'ul'数字常量。所以我会写类似
的东西const uint32_t MAX_INTERVAL = std::numeric_limits<uint32_t>::max();
const int64_t some_var = MAX_INTERVAL;
答案 0 :(得分:3)
如果你有至少33位long
s没有问题(或者更具体地说,如果4294967295可以表示为long
)。行为将被很好地定义为数字可以表示为long
。
如果你有32位long
,那么问题仍然存在。然后行为是实现定义的,这意味着编译器/实现被强制指定行为(最有可能你最终得到-1
,但是可能存在奇怪的实现,这会产生另一个结果)。
标准的相关部分是4.7(积分转换):
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模数) 2 ^ n在哪里 ñ 是用于表示无符号类型的位数)。 [ 注意: 在一个两个 补码表示,这种转换是概念性的,并且位模式没有变化(如果有的话) 不是截断)。 - 注意 ]
- 醇>
如果目标类型已签名,则如果可以在目标类型中表示该值,则该值不会更改(和 位域宽度);否则,该值是实现定义的。