可以从硬编码的整数常量中删除"LL",并将其替换为"static_cast <uint64_t>(...)"吗?

Dan*_*aum 3 c++

我正在修改遗留代码,该代码利用LL硬编码常量的"long long"()数据类型定义,如下所示:

0xFFFFFFFFFFFFFFFFLL
Run Code Online (Sandbox Code Playgroud)

我相信LL附加到常量保证这个常量将被解释为a long long.

但是,我不希望依赖于long long位数方面的任何特定的编译器相关解释.

因此,我希望我的变量声明不LL使用常量,而是使用:

uint64_t a = static_cast<uint64_t>(0xFFFFFFFFFFFFFFFF);
Run Code Online (Sandbox Code Playgroud)

我想0xFFFFFFFFFFFFFFFF在编译时,编译器不会将常量解释为32位整数uint64_t,这将导致a包含该值的64位整数0xFFFFFFFF,而不是所需的值.

(我目前感兴趣的64位编译器是VS 2010和Ubuntu 12.04 LTS GCC.但是,我希望这段代码能够以任何现代编译器的方式运行.)

上面的代码是否可以满足大多数或所有现代编译器的需要,因此a正确设置的值可以根据需要从常量中包含所有数字0xFFFFFFFFFFFFFFFF,而不包括常量LL的末尾?

(注意:包含I64在常量的末尾会产生编译错误.也许还有另一个令牌需要(或可以)包含在常量的末尾,以告诉编译器将常量解释为64位整数?)

(另外:甚至可能static_cast<uint64_t>是不必要的,因为变量显式被定义为uint64_t?)

And*_*owl 5

根据C++ 11标准的第2.1.14/2段:

整数文字的类型是表6中相应列表的第一个,其中可以表示其值

表6指定对于十六进制文字常量,文字的类型应为:

  • int; 或(如果不合适)
  • unsigned int; 或(如果不合适)
  • long int; 或(如果不合适)
  • unsigned long int; 或(如果不合适)
  • long long int; 或(如果不合适)
  • unsigned long long int.

如果我们做出的合理假设0xFFFFFFFFFFFFFFFF不适合上面列表中的前5种类型中的任何一种,那么它的类型应该是unsigned long long int.只要您使用64位编译器,可以合理地假设此类型的值将具有64位的大小,并且常量将被解释为64位unsigned long long int,如您所希望的那样.


Ste*_*sop 5

为了减少什么安迪说的要领:如果实现了一个或多个标准的整数类型,它能够代表的0xFFFFFFFFFFFFFFFF,则文本0xFFFFFFFFFFFFFFFF具有一个的类型。

哪个对你来说并不重要,因为无论是哪个,转换为的结果uint64_t都是一样的。

如果(C++11 之前的)实现没有任何足够大的整数类型,那么 (a) 程序格式错误,因此您应该获得诊断信息;(b)反正它可能不会有uint64_t

你是对的,这static_cast是不必要的。它执行与分配给uint64_t无论如何都会执行的相同转换。有时,强制转换会抑制您因某些隐式整数转换而收到的编译器警告,但我认为在这种情况下,任何编译器都不可能对隐式转换发出警告。通常不会有一个,因为0xFFFFFFFFFFFFFFFF通常已经有类型uint64_t了。

顺便说一句,最好编写static_cast<uint64_t>(-1),或者只是uint64_t a = -1;. 它保证是相等0xFFFFFFFFFFFFFFFF的,但它更容易为读者看到的区别-10xFFFFFFFFFFFFFFF比它看到的区别0xFFFFFFFFFFFFFFFF0xFFFFFFFFFFFFFFF

  • 我希望有人会提到旁边。当 unsigned -1 被定义为最大值时,没有理由尝试提出确切的最大值并希望它会起作用。 (2认同)