int加上unsigned int返回一个无符号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;
}发布于 2012-04-07 02:36:31
如果你说的“应该是”你的意思是“我的编译器是否按照标准运行”:yes。
C++2003:第5条第9段:
许多需要算术或枚举类型的操作数的二元运算符都会导致转换,并以类似的方式生成结果类型。目的是生成一个公共类型,这也是结果的类型。此模式称为通常的算术转换,其定义如下:
如果其中一个操作数是无符号的,则另一个操作数应转换为无符号的。
如果你说“应该是”,你的意思是“如果不是,世界会变得更好吗?”:我没有能力回答这个问题。
发布于 2015-03-31 00:08:04
无符号整数类型主要表现为相当于mod 2^N的值的包装抽象代数环的成员;人们可能不会将N位无符号整数视为表示特定整数,而是将具有特定值的所有整数的集合视为底部N位。例如,如果将最后4位是...1001和...0101的两个二进制数相加,结果将是...1110。如果将...1111和...0001相加,则结果为...0000;如果从...0000中减去...0001,则结果为...1111。请注意,上溢或下溢的概念实际上没有任何意义,因为操作数的高位值是未知的,并且结果的高位值也不重要。另请注意,添加一个高位为“不知道/不关心”的有符号整数,应该会产生一个高位为“不知道/不关心”的数字(这是无符号整数类型的主要行为)。
无符号整数类型不能作为包装代数环的成员的唯一地方是,当它们参与比较时,被用于数值除法(这意味着比较),或者被提升为其他类型。如果将无符号整数类型转换为更大类型的唯一方法是使用运算符或函数来实现此目的,那么使用这样的运算符或函数可以清楚地表明它是在对高位进行假设(例如,将“一些低位为...00010110的数字”转换为“低位为...00010110且高位全为0的数字”)。不幸的是,C不能做到这一点。将带符号的值添加到大小相等的无符号值会产生类似大小的无符号值(这对于上面对无符号值的解释是有意义的),但是向无符号类型添加更大的有符号整数将导致编译器默默地假设后者的所有高位都是零。根据编译器的升级规则,某些编译器可能认为两个表达式具有相同的大小,而另一些编译器可能将它们视为不同的大小,这种情况下,这种行为可能会特别令人头疼。
发布于 2017-12-26 20:19:45
这种行为很可能源于指针类型(内存位置,例如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
https://stackoverflow.com/questions/10047614
复制相似问题