我正在修改遗留代码,该代码利用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?)
根据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,如您所希望的那样.
为了减少什么安迪说的要领:如果实现了一个或多个标准的整数类型,它能够代表的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的,但它更容易为读者看到的区别-1和0xFFFFFFFFFFFFFFF比它看到的区别0xFFFFFFFFFFFFFFFF和0xFFFFFFFFFFFFFFF。
| 归档时间: |
|
| 查看次数: |
646 次 |
| 最近记录: |