c++ - 一元运算符 "-"对 C/C++(以及不同的编译器)中的无符号数据类型有何作用?

标签 c++ c compiler-construction unsigned

例如:

unsigned int numA = 66; // or anything really
unsigned int numB = -numA;
unsigned int numC = numA & numB

我知道按位补码运算符可用于获取二进制补码(结合 +1)。

我问的原因是因为我在国际象棋引擎的一些代码中偶然发现了这个。国际象棋引擎会做很多“hacky”的事情来获得绝对速度,尤其是在每秒调用数百万次的移动生成函数中。 (这无济于事,它是魔术位板移动生成的一个例子——最优化的)。特别是这个国际象棋引擎代码只能在 gcc 编译下正常工作(我怀疑)。

不同的编译器如何处理这个问题?特别是,与 VS Studio 2012 Express 中的 C++ 编译器相比,gcc 如何处理这个问题。

谢谢。

最佳答案

标准中的相关引用实际上是这样的:

(§5.3.1/8) The operand of the unary - operator shall have arithmetic or unscoped enumeration type and the result is the negation of its operand. Integral promotion is performed on integral or enumeration operands. The negative of an unsigned quantity is computed by subtracting its value from 2n, where n is the number of bits in the promoted operand. The type of the result is the type of the promoted operand.

(这是来自 C++11;在旧版本中它曾经是 5.3.1/7。)

因此 -num 将计算为 2CHAR_BIT*sizeof(num) - num (‡)。结果将与操作数具有相同的类型(整数提升后),即它也将是无符号的。

我刚刚用 GCC 进行了测试,它似乎完全按照标准描述的方式执行操作。我假设 Visual C++ 也是如此;否则就是错误。


(‡) 此公式假定相关的位数 对应于内存中变量的大小(以位为单位)。正如 Keith Thompson 在评论中指出的那样,如果存在填充位(即,当并非所有位都参与数值表示时,根据 §3.9.1/1 这是可能的),这就不可能成立。在使用比用于表示数值更多的位来存储值的系统上,公式将不准确。 (不过,就我个人而言,我实际上并不知道有任何这样的系统。)

关于c++ - 一元运算符 "-"对 C/C++(以及不同的编译器)中的无符号数据类型有何作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14065337/

相关文章:

c - 当有多个间接级别时如何解释 volatile

c - 使用结构和数组的 Strcmp 的 If 语句不起作用

c++ - 寄存器分配算法

c++ - 如何在 C++/Linux 中执行外部命令?

C# 内部 == 公共(public) C++

sin 到 std::sin 的 C++ 别名——需要草率的快速修复

c - 使用 printf 的 Linux 的 gotoxy() 实现

c# - C# 编译器是否足够智能来优化此代码?

gcc 失败,生成 : No such file or directory

c++ - 声明指向不同字符串的二维指针数组(在二维数组中)