【发布时间】:2020-04-21 14:13:20
【问题描述】:
在使用更大的程序时,我发现了一个行为异常的片段:
long L = 2500000000L;
fprintf( stderr, "L is %ld\n", L );
fflush( stderr );
由于 L 的声明是 long 并且格式是 %ld,我希望看到这个打印像“2500000000”,但它实际上打印了
L is -1794967296
这更符合我对%d 格式的期望。
但是,如果我将格式更改为 %uld,它会正确打印 2500000000,尽管编译器会发出警告说 L 应声明为 unsigned。
这是 C++ 格式的错误吗?我在 Windows 上使用 Eclipse + mingw,将方言指定为 c++11。
【问题讨论】:
-
也许你应该添加一个断言
long的大小足以容纳该数字并且它不仅仅是 32 位整数(在这种情况下它将超出正数long的范围数字)(长为 32 位是 Windows 上的常见情况)。static_assert(8 == sizeof(L), "too small"); -
带符号的 long 不能保存该值,因此您会看到未定义的行为在第一种情况下表现为环绕,在第二种情况下表现为您的预期值。
-
见en.cppreference.com/w/cpp/language/types,
long在windows上通常是32位,在64位macos和Linux上只有64位 -
使用直接列表初始化来防止潜在的缩小可能也是一个好主意
long L{2500000000L}; -
我相信 2,500,000,000(请检查我的 0 计数)略大于 2**31-1,最大的 32 位有符号整数,但应该很好地适合有符号 64 的范围位整数。 user7860670 建议的断言没有失败。
标签: c++ formatting