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

时间:2013-04-02 16:23:31

标签: c++

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

0xFFFFFFFFFFFFFFFFLL

我相信附加到常量的LL保证此常量将被解释为long long

但是,我不想依赖于long long在位数方面有任何特定的编译器相关解释。

因此,我希望我的变量声明在常量中没有LL,而是使用:

uint64_t a = static_cast<uint64_t>(0xFFFFFFFFFFFFFFFF);

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

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

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

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

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

2 个答案:

答案 0 :(得分: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,如您所希望的那样

答案 1 :(得分:4)

减少Andy所说的要点:如果实现有一个或多个能够表示0xFFFFFFFFFFFFFFFF的标准整数类型,那么文字0xFFFFFFFFFFFFFFFF一个那些类型。

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

如果(pre-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之间的区别{1}}。