我注意到许多C/C++程序员使用以下内容实现了一组标志:
#define FLAG_1 (1 << 0)
#define FLAG_2 (1 << 1)
#define FLAG_3 (1 << 2)
unsigned int my_flags = 0; /* no flag set */
my_flags |= FLAG_2; /* set flag 2 */
Run Code Online (Sandbox Code Playgroud)
但这种方法听起来有效吗?在我看来,它正在假设无符号整数的二进制表示,而不是C/C++语言标准的一部分.例如,"0"实际上是0x0000.
我错了吗?或者我在理论上是正确的,但在目前的标准硬件中没有实践吗?
Jos*_*eld 18
C++ 11标准的重要部分是§3.9.1/ 7(ISO/IEC 14882:2011(E)):
整数类型的表示应使用纯二进制计算系统定义值.
这在脚注中阐明:
49)使用二进制数字0和1的整数的位置表示,其中由连续位表示的值是加法的,以1开始,并且乘以2的连续积分幂,除了可能对于具有最高位置的位.(改编自美国国家信息处理系统词典.)
移位运算符的结果是数学定义的.例如,对于E1 << E2:
如果E1具有无符号类型,则结果的值为E1×2 E2,比结果类型中可表示的最大值减少一个模数.否则,如果E1具有有符号类型和非负值,并且在结果类型中可以表示E1×2 E2,那么这就是结果值; 否则,行为未定义.
按位运算符具体定义为按位.例如,对于按位OR:
执行通常的算术转换; 结果是操作数的按位异或功能.
当然,在as-if规则下,表示并不一定是纯二进制计算系统.编译器必须只生成一个像它一样的程序.
在C99(ISO/IEC 9899:TC3)中,仅对位域和类型对象unsigned char(§6.2.6.1/ 3)保证纯二进制表示法:
存储在无符号位域中的值和unsigned char类型的对象应使用纯二进制表示法表示.
再次在脚注中澄清:
使用二进制数字0和1的整数的位置表示,其中由连续位表示的值是加法的,以1开始,并且乘以连续的2的整数幂,除了具有最高位置的位.(改编自美国国家信息处理系统词典.)
该标准特别指出按位运算取决于内部表示(第6.5/4节):
一些运算符(一元运算符〜,以及二元运算符<<,>>,&,^和|,统称为按位运算符)需要具有整数类型的操作数.这些运算符产生的值取决于整数的内部表示,并且具有已签名类型的实现定义和未定义方面.
当前的C和C++标准都将无符号整数表示限制为纯二进制表示,因此您拥有的内容完全安全并且保证可以正常工作.
| 归档时间: |
|
| 查看次数: |
889 次 |
| 最近记录: |