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

问题描述 投票:10回答:2

问题很清楚。

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

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

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

由于某种原因,它似乎与STL的设计不兼容......

c++ qt qt4
2个回答
5
投票

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

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

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


10
投票

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

Chris对签名大小类型的理由是它们自然地用作数组索引,并且您可能希望对数组索引进行算术运算,并且该算法可能会创建负数的临时值。

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

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

[a,b]

这不适用于带符号的变量;这种范围检查在大小和数组偏移方面非常常见。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.