gpt4 book ai didi

c++ - 为什么 QVector::size 返回 int?

转载 作者:IT老高 更新时间:2023-10-28 21:52:42 27 4
gpt4 key购买 nike

std::vector::size() 返回一个无符号的 size_type,通常与 size_t 相同,例如在 64 位平台上是 8 个字节。

相比之下,QVector::size() 返回一个 int,即使在 64 位平台上通常也是 4 个字节,并且它是有符号的,这意味着它可以只走到2^32的一半。

这是为什么呢?这似乎很不合逻辑,而且在技术上也有限制,虽然您可能需要超过 2^32 个元素的可能性也不大,但使用有符号 int 会毫无理由地将该范围缩小一半。也许是为了避免对那些懒得将 i 声明为 uint 而不是决定让所有容器返回大小类型的 int 的人发出编译器警告这没有任何意义是更好的解决方案吗?原因不可能这么傻吧?

最佳答案

至少从 Qt 3 开始,这个问题已经讨论过好几次了,QtCore 维护者表示不久前不会发生任何变化,直到 Qt 7 才会发生。

当时进行讨论时,我认为迟早会有人在 Stack Overflow 上提出它……而且可能还会在其他几个论坛和 Q/A 上提出。让我们试着揭开这种情况的神秘面纱。

一般而言,您需要了解这里没有更好或更差,因为 QVector 不是 std::vector 的替代品。后者不执行任何写时复制 (COW),而且这是有代价的。基本上,它适用于不同的用例。它主要用于 Qt 应用程序和框架本身,最初用于早期的 QWidgets。

size_t 也有它自己的问题,毕竟我将在下面指出。

无需我向您解释维护者,我将直接引用蒂亚戈来传递 official stance 的信息。上:

For two reasons:

1) it's signed because we need negative values in several places in the API: indexOf() returns -1 to indicate a value not found; many of the "from" parameters can take negative values to indicate counting from the end. So even if we used 64-bit integers, we'd need the signed version of it. That's the POSIX ssize_t or the Qt qintptr.

This also avoids sign-change warnings when you implicitly convert unsigneds to signed:

-1 + size_t_variable        => warning
size_t_variable - 1 => no warning

2) it's simply "int" to avoid conversion warnings or ugly code related to the use of integers larger than int.

io/qfilesystemiterator_unix.cpp

size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX);
if (maxPathName == size_t(-1))

io/qfsfileengine.cpp

if (len < 0 || len != qint64(size_t(len))) {

io/qiodevice.cpp

qint64 QIODevice::bytesToWrite() const
{
return qint64(0);
}

return readSoFar ? readSoFar : qint64(-1);

这是蒂亚戈的一封电子邮件,然后是 there is another你可以在哪里找到一些详细的答案:

Even today, software that has a core memory of more than 4 GB (or even 2 GB) is an exception, rather than the rule. Please be careful when looking at the memory sizes of some process tools, since they do not represent actual memory usage.

In any case, we're talking here about having one single container addressing more than 2 GB of memory. Because of the implicitly shared & copy-on-write nature of the Qt containers, that will probably be highly inefficient. You need to be very careful when writing such code to avoid triggering COW and thus doubling or worse your memory usage. Also, the Qt containers do not handle OOM situations, so if you're anywhere close to your memory limit, Qt containers are the wrong tool to use.

The largest process I have on my system is qtcreator and it's also the only one that crosses the 4 GB mark in VSZ (4791 MB). You could argue that it is an indication that 64-bit containers are required, but you'd be wrong:

  • Qt Creator does not have any container requiring 64-bit sizes, it simply needs 64-bit pointers

  • It is not using 4 GB of memory. That's just VSZ (mapped memory). The total RAM currently accessible to Creator is merely 348.7 MB.

  • And it is using more than 4 GB of virtual space because it is a 64-bit application. The cause-and-effect relationship is the opposite of what you'd expect. As a proof of this, I checked how much virtual space is consumed by padding: 800 MB. A 32-bit application would never do that, that's 19.5% of the addressable space on 4 GB.

(padding is virtual space allocated but not backed by anything; it's only there so that something else doesn't get mapped to those pages)

通过蒂亚戈的回答进一步探讨这个话题,请参阅:

Personally, I'm VERY happy that Qt collection sizes are signed. It seems nuts to me that an integer value potentially used in an expression using subtraction be unsigned (e.g. size_t).

An integer being unsigned doesn't guarantee that an expression involving that integer will never be negative. It only guarantees that the result will be an absolute disaster.

另一方面,C 和 C++ 标准定义了无符号的行为 上溢和下溢。

有符号整数不会上溢或下溢。我的意思是,他们这样做是因为类型 和 CPU 寄存器的位数有限,但标准说它们 不。这意味着编译器将始终优化假设您没有过度 - 或下溢。

例子:

for (int i = 1; i >= 1; ++i)

This is optimised to an infinite loop because signed integers do not overflow. If you change it to unsigned, then the compiler knows that it might overflow and come back to zero.

Some people didn't like that: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475

关于c++ - 为什么 QVector::size 返回 int?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26619863/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com