对象大小限制下的行为

Nei*_*eil 2 c language-lawyer

C99 第 6.5.6 节,

如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则求值不会产生溢出;否则,行为是未定义的

size_t是 [0..3] 之一。如果char数组大小为 4,索引为 [0..3],最后一个元素后面的一个元素将为索引 4,这会溢出size_t。那么,SIZE_MAX - 1由于这种情况,最大对象大小(以字节为单位)会是 3, [0..2], 最大索引 吗?换句话说,SIZE_MAX是否保证不是有效的数据索引?

第 6.5.3.3 节,

如果提升的类型是无符号类型,则表达式 ~E 相当于该类型可表示的最大值减去 E。

这始终是2^n-1奇数。

And*_*zel 5

首先,一些背景信息:

\n

ISO C11 标准的 \xc2\xa77.20.3 \xc2\xb62规定数据类型size_t必须能够表示至少为 的数字65535,即SIZE_MAX必须具有至少为 的值65535

\n

\xc2\xa75.2.4.1 \xc2\xb61规定实现必须支持65535托管环境中至少字节的对象大小(但对于独立环境没有这样的要求)。

\n

然而,这两个数字相同并不意味着实现的最大支持对象大小必须等于SIZE_MAX。这是因为上面提到的数字仅代表实现必须支持的最低限制。

\n

\xc2\xa76.5.6 \xc2\xb68规定,在执行指针算术时,如果指针操作数和指针结果都指向同一数组对象的元素,或者超过了最后一个元素,则指针不应溢出那个数组对象。

\n

标准的该部分没有指定数据类型size_t必须能够表示对象的所有索引。然而,\xc2\xa76.5.3.4确实暗示了这一点,它指出运算符的结果是表示对象大小(以字节为单位)的sizeof类型值。size_t通过这样做,该标准意味着数据类型size_t必须能够表示对象的大小,这也意味着size_t必须能够表示对象的最后一个有效索引之后的索引,因为该索引与对象的大小,假设数组的元素类型为char

\n

现在,回答你的问题:

\n
\n

size_t是 [0..3] 之一。如果char数组大小为 4,索引为 [0..3],最后一个元素后面的一个元素将为索引 4,这会溢出size_t。那么,SIZE_MAX - 1由于这种情况,最大对象大小(以字节为单位)会是 3, [0..2], 最大索引 吗?换句话说,SIZE_MAX是否保证不是有效的数据索引?

\n
\n

对,那是正确的。兼容的实现将无法支持大小4或更大的对象,因为它将无法使sizeof操作员使用它们,如标准的 \xc2\xa76.5.3.4 中所指定的。

\n