0xfffffffful为(签名)长:ub,stramp newine或ok ok

0xFFFFFFFFul as (signed) long: UB, Impl-defined or just OK?

本文关键字:ok stramp ub newine 签名 0xfffffffful      更新时间:2023-10-16

将在所有理智(例如2-S补体算术)32位计算机上打印-1,llp64上的-1(即64位窗口,长为32位,)和所有64位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;

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

如果您有32位long S,仍然没有问题。然后定义了该行为,这意味着编译器/实现是要求指定行为的(很可能您最终会使用-1,但是可能存在奇特的实现,这将产生另一个结果)。

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

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

  2. 如果目标类型已签署,则值在目标类型中表示(和 位宽度);否则,该值是实现定义的。