Section 6.5.6 C99,
If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined
Say size_t
is one of [0..3]. If a char
array were size 4, index [0..3], one past the last element would be index 4, which overflows size_t
. Would, then, the maximum object size in bytes be 3, [0..2], maximum index SIZE_MAX - 1
, because this condition? In other words, SIZE_MAX
is guaranteed to not be a valid index of data?
Section 6.5.3.3,
If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.
Which is always 2^n-1
, an odd number.
CodePudding user response:
First, a bit of background:
§7.20.3 ¶2 of the ISO C11 standard states that size_t
must be able to represent numbers up to at least 65535
, i.e. that SIZE_MAX
must have a value of at least 65535
.
§5.2.4.1 ¶1 states that an implementation must support object sizes of at least 65535
bytes in a hosted environment (but states no such requirement for a freestanding environment).
However, the fact that these two numbers are identical does not mean that an implementation's maximum supported object size must be equal to SIZE_MAX
. That is because the numbers mentioned above only represent minimum limits that the implementation must support.
§6.5.6 ¶8 states that when performing pointer arithmetic, that the pointer shall not overflow, if the pointer operand and the pointer result both point to an element of the same array object, or one past the last element of that array object.
That section of the standard does not specify that an object of size_t
must be able to represent all indexes of an object. However, §6.5.3.4 does imply this, by stating that the result of the sizeof
operator is a value of type size_t
that represents the size of the object in bytes. By doing this, the standard implies that the data type size_t
must be able to represent the size of the object, which also implies that size_t
must be able to represent the index one past the last valid index of the object, because that index is identical to the size of the object, assuming that the array's elements are of type char
.
Now, to answer your question:
Say
size_t
is one of [0..3]. If achar
array were size 4, index [0..3], one past the last element would be index 4, which overflowssize_t
. Would, then, the maximum object size in bytes be 3, [0..2], maximum indexSIZE_MAX - 1
, because this condition? In other words,SIZE_MAX
is guaranteed to not be a valid index of data?
Yes, that is correct. A compliant implementation would not be able to support objects of size 4
or larger, because it would be unable to make the sizeof
operator work with them, as specified in §6.5.3.4 of the standard.