【问题标题】:Why is std::list bigger on c++11?为什么 c++11 上的 std::list 更大?
【发布时间】:2012-04-08 18:01:36
【问题描述】:

使用此代码:

#include <iostream>
#include <list>

int main() {
    std::cout << sizeof(std::list<void*>) << std::endl;
};

我设法注意到,在 GCC 4.7 上,std::list&lt;void*&gt; 在 C++98 上的大小是 16 字节,而在 C++11 上它的大小是 24 字节。

我想知道 std::list 发生了什么变化,使它变大了。

【问题讨论】:

  • 从技术角度来看,这种行为完全是特定于实现的。如果他们愿意,图书馆作者可以任意决定将类扩大 100 倍,而无需任何理由。编写任何取决于列表大小正好为 16 字节的代码可能不是一个好主意。你在做什么,这实际上导致了一个错误?
  • 看看这里:en.cppreference.com/w/cpp/container/list 你会看到一些成员类型在 c++11 的 std::list 中发生了变化。
  • 他们可能缓存了列表大小。 24 字节是三个 64 位值 - 一个开始指针、一个结束指针和一个大小。
  • 没有注意到,我正在将 C++98 库与 C++11 应用程序链接起来。由于 std::list 导致的不同类内存布局,这个库有一些内联 getter 得到错误的内存变量。
  • @dexametason- 很抱歉,我没有看到任何会迫使实现使用更大尺寸的接口更改。你能具体指出你指的是什么吗?

标签: c++ gcc c++11 c++98


【解决方案1】:

C++11 要求list::size() 在恒定时间内执行。 GCC 通过adding the size as a data member 使这成为可能。 GCC 在 C++98 模式下没有这样做,因为这会破坏二进制兼容性。

不要将在 C++98 模式下编译的代码与在 C++11 模式下编译的代码混用。它不起作用。

更新:显然,GCC 的人改变了主意,现在 C++11 的一致性不如保持兼容性重要,所以list::size() 将不再在恒定时间内执行GCC 4.7.2。它将在未来的版本中,在 C++98 和 C++11 模式下。

【讨论】:

  • std::list&lt;T&gt;::splice 现在的复杂度是多少?
  • @André :这取决于您调用的重载。有些重载是 O(1),有些是 O(N)。
  • 您需要更新 size 字段,因此您需要计算迭代器引用的项目数量。
  • 两个和三个参数拼接是常数时间,四个参数版本(从列表上的迭代器范围)在迭代器范围距离中是线性的,除非 &from == this 在这种情况下它是常数时间。
  • @emsr 这就是标准的要求,你检查过还是检查过 GCC 的实现是否符合这方面的要求?
猜你喜欢
  • 2012-10-17
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
  • 2014-10-09
相关资源
最近更新 更多