为什么int加上uint会返回uint?

时间:2012-04-06 18:28:53

标签: c++ int unsigned integer-arithmetic

int plus unsigned int返回unsigned int。应该这样吗?

考虑以下代码:

#include <boost/static_assert.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>

class test
{
    static const int          si = 0;
    static const unsigned int ui = 0;

    typedef BOOST_TYPEOF(si + ui) type;
    BOOST_STATIC_ASSERT( ( boost::is_same<type, int>::value ) ); // fails
};


int main()
{
    return 0;
}

3 个答案:

答案 0 :(得分:14)

如果“应该是”,则表示“我的编译器是否符合标准”:

C ++ 2003:第5条第9款:

  

许多期望算术或枚举类型操作数的二元运算符会导致转换和产生   结果类型以类似的方式。目的是产生一个通用类型,它也是结果的类型。   这种模式称为通常的算术转换,定义如下:

     
      
  • 嗒嗒
  •   
  • 否则, blah
  •   
  • 其他,等等,...
  •   
  • 否则,如果任一操作数是无符号的,则另一个操作数应转换为无符号。
  •   

如果“应该是”,那么你的意思是“如果世界不是一个更好的地方”:我没有能力回答这个问题。

答案 1 :(得分:0)

无符号整数类型主要表现为包含抽象代数环的成员,其值等于mod 2 ^ N;可以查看N位无符号整数,而不是表示特定整数,而是查看底部N位中具有特定值的所有整数的集合。例如,如果将最后4位为...1001...0101的两个二进制数加在一起,结果将为...1110。如果添加...1111...0001,则结果为...0000;如果从...0001中减去...0000,结果将为...1111。注意,上溢或下溢的概念实际上并不意味着什么,因为操作数的高位值是未知的,并且结果的高位值是不感兴趣的。另请注意,添加一个有符号整数,其高位对于其高位是“不知道/不关心”的人来说是已知的。应该产生一个数字,其高位是&#34;不知道/不关心&#34; (这是无符号整数类型的行为)。

无符号整数类型无法作为包裹代数环的成员行为的唯一地方是它们参与比较时,用于数字划分(这意味着比较),或者被提升为其他类型。如果将无符号整数类型转换为更大的类型的唯一方法是使用运算符或函数来实现该目的,那么使用这样的运算符或函数可以清楚地表明它正在对高位进行假设(例如转向&#34 ;某些数字的低位为...00010110&#34;进入&#34;低位为...00010110且高位为全零的数字。不幸的是,C不这样做。将有符号值添加到相等大小的无符号值会产生类似大小的无符号值(这对于上面的无符号值的解释是有意义的),但是对无符号类型添加更大的有符号整数将导致编译器静默地假设所有后者的高位是零。在某些情况下,这种行为尤其令人烦恼,具体取决于编译器和编译器。促销规则,一些编制者可能认为两个表达具有相同的大小,而其他人可能将它们视为不同的大小。

答案 2 :(得分:0)

行为可能源于指针类型背后的逻辑(内存位置,例如std::size_t)加上内存位置差异(std::ptrdiff_t)也是内存位置。

换句话说,std::size_t = std::size_t + std::ptrdiff_t

当此逻辑转换为底层类型时,这意味着unsigned long = unsigned long + longunsigned = unsigned + int

&#34;其他&#34;来自@supercat的解释也可能是正确的。