【发布时间】:2013-04-12 15:17:04
【问题描述】:
当我将std::abs(int) 与unsigned 进行比较时,我收到了有关有符号与无符号比较的警告。事实上,std::abs 返回有符号值。为什么会做出这样的选择?它本来可以解决负值的绝对值不能用有符号类型表示的问题。
然后,有没有比这更干净(即没有演员表)的东西来避免警告?
#include <cassert>
#include <cstdlib>
// max(1, lhs + rhs). (lhs must be > 0)
unsigned add(unsigned lhs, int rhs)
{
return
(0 < rhs || static_cast<unsigned>(-rhs) < lhs
? rhs + lhs
: 1);
}
int main()
{
assert(add(42, -41) == 1);
assert(add(42, 0) == 43);
assert(add(42, 1) == 43);
assert(add(42, -51) == 1);
}
【问题讨论】:
-
我怀疑这对标准原理有多大影响,但实际上并不能保证
unsigned可以代表int的每个绝对值。理论上,您可以有一个一致的实现,其中int是 33 位 2 的补码,unsigned是 32 位。在该实现中,int和unsigned都不能代表INT_MIN的绝对值。当然,不确定您为什么想要这样的实现,但它是合法的,因此您的提议并没有严格解决问题。该标准仍然允许您无法执行abs(INT_MIN)! -
在实践中,有一个
int的值是你不能做abs的事实并不比有一个int的值更麻烦你不能在上面做--。同样是一个你不能做的值++。 C 和 C++ 的作者并不讨厌未定义的溢出行为以将其删除。 -
@SteveJessop 给定 §3.9.1-3 怎么可能(
unsigned int和int的存储量和对象表示相同)? -
@ChristianRau:不同数量的填充位。位是否参与值不是对象表示的一部分,它是值表示的一部分。这很学术,但 C 和 C++ 决心允许有趣的架构。我说好笑:快要好笑了。 32 和 31 比 33 和 32 更合理,但是,8 位字节。我不确定,但我认为可能有一些机器在无符号类型中未使用符号位(尽管
unsigned char必须使用它)。他们是否有符合标准的 C++ 编译器是另一回事。 -
克雷没有这样的
int类型吗? IIRC 它使用float布局,但指数位设置为零。对于unsigned int,可能符号位也设置为零。
标签: c++ unsigned signed gcc-warning