一开始可能会想std::numeric_limits<size_t>::max()
,但如果有一个这么大的对象,它还能提供一个过去的指针吗?我猜不是。这是否意味着sizeof(T)
可以产生的最大价值是std::numeric_limits<size_t>::max()-1
?我是对的,还是我错过了什么?
7 回答
问:sizeof(T) 可以产生的最大值是多少?
A: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";
}
如果您可以通过从过去的指针中减去指向它的指针来std::numeric_limits<ptrdiff_t>::max() > std::numeric_limits<size_t>::max()
计算大小对象的大小。std::numeric_limits<size_t>::max()
如果sizeof(T*) > sizeof(size_t)
您可以有足够多的不同指针来寻址该对象内的每个字节(例如,如果您有一个 char 数组),再加上一个用于结束的指针。
因此,可以编写一个实现 where sizeof
can return std::numeric_limits<size_t>::max()
,并且您可以在其中获得指向这么大对象的过去的指针。
它的定义并不完全明确。但要保持在标准的安全范围内,最大对象大小为std::numeric_limits<ptrdiff_t>::max()
那是因为当你减去两个指针时,你会得到一个ptrdiff_t
这是一个有符号整数类型
干杯&hth.,
能够指向数组末尾之外的要求与 的范围无关size_t
。给定一个 object x
,它很有可能(&x)+1
是一个有效的指针,即使分隔两个指针的字节数不能用size_t
.
您可能会争辩说,该要求确实暗示了最大指针范围的对象大小的上限,减去对象的对齐方式。但是,我不相信标准在任何地方都说不能定义这种类型。实例化一个并且仍然保持一致是不可能的。
如果这是一个测试,我会说(size_t) -1
sizeof()
表达式产生一个类型的值size_t
。从 C99 标准 6.5.3.4 开始:
结果的值是实现定义的,其类型(无符号整数类型)是 size_t,在 stddef.h(和其他头文件)中定义。
因此,sizeof() 可以产生的最大值是 SIZE_MAX。
您可以拥有一个兼容标准的编译器,该编译器允许导致指针运算溢出的对象大小;但是,结果是不确定的。从 C++ 标准,5.7 [expr.add]:
当两个指向同一个数组对象的元素的指针相减时,结果就是两个数组元素的下标之差。结果的类型是实现定义的有符号整数类型;此类型应与标题 (18.2) 中定义的类型
std::ptrdiff_t
相同<cstddef>
。与任何其他算术溢出一样,如果结果不适合提供的空间,则行为未定义。