12

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;
}
4

3 回答 3

16

如果“应该”是指“我的编译器是否按照标准运行”:的。

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

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

  • 废话
  • 否则,废话
  • 否则,废话,...
  • 否则,如果任一操作数是无符号的,则另一个应转换为无符号。

如果“应该”是指“如果没有,世界会变得更美好吗”:我没有能力回答这个问题。

于 2012-04-06T18:36:31.370 回答
2

无符号整数类型主要表现为包装抽象代数环的成员,这些值等效于 mod 2^N; 人们可能会认为 N 位无符号整数不是表示特定整数,而是在底部 N 位中具有特定值的所有整数的集合。例如,如果将后 4 位为...1001和的两个二进制数相加...0101,则结果将是...1110。如果加一个...1111and ...0001,结果将是...0000; 如果...0001...0000结果中减去一个将是...1111. 请注意,上溢或下溢的概念实际上并没有任何意义,因为操作数的高位值是未知的,而结果的高位值是不感兴趣的。另请注意,将其高位已知的有符号整数与高位为“不知道/不关心”的整数相加应该产生一个高位为“不知道/不关心”的数字(其中是无符号整数类型的主要行为)。

无符号整数类型无法充当环绕代数环成员的唯一地方是当它们参与比较、用于数值除法(这意味着比较)或提升为其他类型时。如果将无符号整数类型转换为更大的类型的唯一方法是为此目的使用运算符或函数,则使用这样的运算符或函数可以清楚地表明它正在对高位进行假设(例如,将“某个数字其低位为...00010110" 成 " 其低位为...00010110并且其高位全为零)。不幸的是,C 没有这样做。将有符号值添加到大小相等的无符号值会产生大小相同的无符号值(这对于上面对无符号值的解释是有意义的),但是将更大的有符号整数添加到无符号类型将导致编译器默默地假设所有后者的高位为零。如果根据编译器的提升规则,某些编译器可能认为两个表达式具有相同的大小,而其他编译器可能将它们视为不同的大小,则这种行为尤其令人烦恼。

于 2015-03-30T16:08:03.797 回答
1

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

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

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

@supercat 的“其他”解释也可能是正确的。

很明显,unsigned整数不是设计的,也不应该被解释为数学上的正数,甚至在原则上也不应该。见https://www.youtube.com/watch?v=wvtFGa6XJDU

于 2017-12-26T12:19:44.720 回答