【问题标题】:0xFFFFFFFFul as (signed) long: UB, Impl-defined or just OK?0xFFFFFFFFul as (signed) long: UB, Impl-defined or just OK?
【发布时间】:2016-06-23 07:01:04
【问题描述】:

此代码是否会在所有健全的(例如 2 秒补码算法)32 位机器上打印 -1,在 LLP64(即 64 位 Windows,其中 long 是 32 位)上打印 -1,在所有 64 位机器上打印 4 gig bit Unix OS:es(即在 LP64 OS:es 上):

#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;

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果您至少有 33 位 longs,则没有问题(或者更具体地说,如果 4294967295 可以表示为 long)。该行为将被很好地定义为数字可以表示为long

    如果你有 32 位的 longs 仍然没有什么问题。然后定义实现行为,这意味着编译器/实现被强制指定行为(很可能您最终会得到-1,但可能存在会产生另一个结果的奇怪实现)。

    标准的相关部分是4.7(积分转换):

    1. 如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2^n 在哪里 n 是用于表示无符号类型的位数)。 [ 笔记: 在一个二 补码表示,这种转换是概念性的,位模式没有变化(如果有 是没有截断)。 ——尾注 ]

    2. 如果目标类型是有符号的,那么如果它可以在目标类型中表示(并且 位域宽度);否则,该值是实现定义的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 2018-03-15
      • 1970-01-01
      相关资源
      最近更新 更多