为什么Qt对其容器类使用有符号整数类型?

时间:2011-02-17 14:20:35

标签: c++ qt qt4

问题很清楚。

我想知道为什么他们甚至认为这会很方便,因为显然负面的indeces在与它们一起使用的容器中是不可用的(参见例如QList's docs)。

我认为他们想要允许一些疯狂的索引形式,但它似乎不受支持?

它还会生成大量(正确的)编译器警告,有关转换和比较有符号/无符号类型(在MSVC上)。

由于某种原因,它似乎与STL不相容......

2 个答案:

答案 0 :(得分:10)

虽然我对克里斯的推理方式深表同情,但我在这里不同意(至少在某种程度上,我扮演的是魔鬼的倡导者)。将无符号类型用于大小没有任何问题,在某些情况下它甚至可能是有益的。

Chris对签名大小类型的理由是它们自然被用作数组索引,你可能想对数组索引进行算术运算,而算术可能会创建负数的临时值。

这很好,无符号算术在这样做时没有问题,只要你确保在进行比较时正确解释你的值。因为无符号整数的溢出行为是完全指定的,所以临时溢出到负范围(或大量正数)只要在执行比较之前纠正它们就不会引入任何错误。

有时,溢出行为甚至是可取的,因为无符号算术的溢出行为使得某些范围检查可以表示为单个比较,否则将需要两次比较。如果我想检查x是否在[a,b]范围内并且所有值都是无符号的,我可以这样做:

if (x - a < b - a) {
}

这对签名变量不起作用;这种范围检查在大小和数组偏移方面非常常见。

我之前提到过,溢出算法已经定义了结果。如果索引算法溢出了签名类型,则行为是实现定义的;没有办法让你的程序可移植。使用无符号类型,这个问题就消失了。不可否认,这仅适用于巨大的偏移量,但对某些用途来说这是一个问题。

基本上,对无符号类型的反对经常被夸大。真正的问题是大多数程序员并没有真正考虑他们编写的代码的确切语义,而对于整数值,签名类型的行为更接近于他们的直觉。但是,数据大小增长得非常快。当我们处理缓冲区或数据库时,我们经常超出“小”的范围,并且有符号溢出比无符号溢出更难以正确处理。解决方案不是“不使用无符号类型”,而是“仔细考虑您正在编写的代码,并确保您理解它”。

答案 1 :(得分:5)

因为,实际上,您通常希望对索引执行算术运算,这意味着您可能希望创建负数的临时值。 当底层索引类型是无符号时,这显然很痛苦。

使用无符号数的唯一合适时间是模数运算。 使用“unsgined”作为某种契约说明符“范围[0 ...”中的数字只是笨拙,太粗糙而无用。

考虑:我应该使用什么类型来表示数字应该是1到10之间的正整数?为什么0 ... 2 ^ x是一个更特殊的范围?