Eri*_*oma 6 c c++ compiler-construction unsigned
例如:
unsigned int numA = 66; // or anything really
unsigned int numB = -numA;
unsigned int numC = numA & numB
Run Code Online (Sandbox Code Playgroud)
我知道可以使用按位补码运算符来获得二进制补码(与+1一起使用).
我问的原因是因为我在国际象棋引擎的一些代码中偶然发现了这个问题.国际象棋引擎做了许多'hacky'事情来获得绝对速度,特别是在每秒数百万次的移动生成功能中.(它是魔术位板移动生成的一个例子 - 它们中最优化的一部分没有帮助).这个国际象棋引擎代码特别只能在gcc编译下正常工作(我怀疑).
不同的编译器如何对待这个?特别是,与VS Studio 2012 Express中的C++编译器相比,gcc如何处理这个问题.
谢谢.
jog*_*pan 12
标准的相关引用实际上是这样的:
(§5.3.1/ 8)一元运算符的操作数应具有算术或无范围的枚举类型,结果是其操作数的否定.对整数或枚举操作数执行整体提升.通过从2 n减去其值来计算无符号数量的负数,其中n是提升的操作数中的位数.结果的类型是提升的操作数的类型.
(这是来自C++ 11;在旧版本中曾经是5.3.1/7.)
因此-num
将被评估为2 CHAR_BIT*sizeof(num) - num (‡).结果将与操作数的类型相同(在整数提升之后),即它也将是无符号的.
我刚刚使用GCC进行测试,它似乎按照标准描述的方式执行操作.我假设这也是Visual C++的情况; 否则这是一个错误.
(‡)此公式假定相关位数对应于内存中变量的大小(以位为单位).正如Keith Thompson在评论中指出的那样,如果存在填充位(即,并非所有位都参与数值的表示,这可能是根据§3.9.1/ 1),则情况不可能如此.在使用更多位来存储值而不是用于表示数值的系统上,公式将不准确.(不过,我个人并不是真的知道任何这样的系统.)