Home > Enterprise >  Behavior at limits of object size
Behavior at limits of object size

Time:12-19

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 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?

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.

  • Related