【问题标题】:What is the largest value sizeof(T) can yield?sizeof(T) 可以产生的最大值是多少?
【发布时间】:2011-12-19 00:11:22
【问题描述】:

一开始可能会想到std::numeric_limits<size_t>::max(),但是如果有一个这么大的对象,它还能提供一个过去的指针吗?我猜不会。这是否意味着sizeof(T) 可以产生的最大值是std::numeric_limits<size_t>::max()-1?我是对的,还是我错过了什么?

【问题讨论】:

  • 对象是否需要提供一个过去的指针?
  • @Dabbler:根据 C++ 标准,是的,因为就指针运算而言,对象可以被视为大小为 1 的数组。如果您愿意,我可以查找确切的措辞.
  • @Mike:错了,5.7 §1 说For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
  • 我没有看到 std::numeric_limits<size_t>::max() large 对象与系统无法提供过去的指针之间的相关性。
  • @Dennis: ...因为 size_t 和 intptr_t 是不同的东西

标签: c++ memory pointers sizeof size-t


【解决方案1】:

问:sizeof(T) 可以产生的最大值是多少?

答:std::numeric_limits<size_t>::max()

很明显,sizeof 不能返回大于std::numeric_limits<size_t>::max() 的值,因为它不适合。唯一的问题是,能不能返回...::max()

是的。这是一个有效的程序,它不违反 C++03 标准的任何约束,它通过示例演示。特别是,该程序不违反 §5.3.3 [expr.sizeof] 和 §8.3.4 [dcl.array] 中列出的任何约束:

#include <limits>
#include <iostream>
int main () {
 typedef char T[std::numeric_limits<size_t>::max()];
 std::cout << sizeof(T)<<"\n";
}

【讨论】:

  • 你真的完整阅读了这个问题吗?弗雷德讨论了为什么他认为这可能是错误的。你怎么能在提问后超过 10 分钟就提供一个与他的疑问相矛盾的答案,甚至不争论?
  • +1,尽管问题仍然是过去的指针将具有什么值。
  • 嗯,在我的电脑上打印4294967295,所以我想我错了。
  • @sbi:公平地说,Rob 举了一个反例证明我错了。
  • 这里有很大的区别“sizeof(T) 可以返回的最大值”和“可以实际实例化的最大变量”(即使忽略任何给定计算机的实际内存容量); -)
【解决方案2】:

如果std::numeric_limits&lt;ptrdiff_t&gt;::max() &gt; std::numeric_limits&lt;size_t&gt;::max(),您可以通过从一个过去的指针中减去指向它的指针来计算大小为std::numeric_limits&lt;size_t&gt;::max() 的对象的大小。

如果sizeof(T*) &gt; sizeof(size_t),您可以有足够多的不同指针来寻址该对象内的每个字节(例如,如果您有一个 char 数组)加上一个用于过去结束的指针。

因此,可以编写一个实现,其中sizeof 可以返回std::numeric_limits&lt;size_t&gt;::max(),并且您可以在其中获得指向如此大的对象的过去的指针。

【讨论】:

  • 如果实现的目标是具有分段地址的平台,sizeof(T*) &gt; sizeof(size_t) 很容易实现。
  • “我怀疑是否存在这样的实现 [sizeof 可以返回 std::numeric_limits&lt;size_t&gt;::max()]”。 g++ 就是这样一种实现。
【解决方案3】:

能够指向数组末尾之外的要求与size_t 的范围无关。给定一个对象x(&amp;x)+1 很有可能是一个有效的指针,即使分隔两个指针的字节数不能用size_t 表示。

您可能会争辩说,要求确实意味着对象大小的上限是指针的最大范围,减去对象的对齐方式。但是,我不相信标准在任何地方都说不能定义这种类型。实例化一个并且仍然保持一致是不可能的。

【讨论】:

    【解决方案4】:

    您可以拥有一个兼容标准的编译器,该编译器允许导致指针运算溢出的对象大小;但是,结果是不确定的。来自 C++ 标准,5.7 [expr.add]:

    当两个指向同一个数组对象的元素的指针相减时, 结果是两个数组的下标之差 元素。结果的类型是实现定义的有符号 积分型;此类型应与定义为的类型相同 std::ptrdiff_t&lt;cstddef&gt; 标头 (18.2) 中。与任何其他 算术溢出,如果结果不适合提供的空间, 行为未定义。

    【讨论】:

      【解决方案5】:

      它的定义并不完全明确。但要保持在标准的安全范围内,最大对象大小为std::numeric_limits&lt;ptrdiff_t&gt;::max()

      那是因为当你减去两个指针时,你会得到一个ptrdiff_t

      这是一个有符号整数类型

      干杯&hth.,

      【讨论】:

      • 遗憾的是,您可以拥有一个大于std::numeric_limits&lt;ptrdiff_t&gt;::max() 的数组。如果您减去此数组中相距太远的两个指针,则行为未定义,请参见 [expr.add]/6。
      • @avakar:我该死!很好的发现。 As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined.
      【解决方案6】:

      sizeof() 表达式产生size_t 类型的值。来自 C99 标准 6.5.3.4:

      结果的值是实现定义的,它的类型(一个 无符号整数类型)是 size_t,在 stddef.h(和其他 标题)。

      因此,sizeof() 可以产生的最大值是 SIZE_MAX。

      【讨论】:

      • 这是size_t 中可以存储的最大值。这并不意味着sizeof 使用了size_t 的所有值。
      【解决方案7】:

      如果这是一个测试,我会说(size_t) -1

      【讨论】:

      • 那是std::numeric_limits&lt;size_t&gt;::max()
      猜你喜欢
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2013-03-18
      • 2012-05-29
      相关资源
      最近更新 更多