ISO/IEC JTC1/SC22/WG14 N708 Issues with size_t and ptrdiff_t ================================ Clive D.W. Feather ================== The type /size_t/ is an unsigned integral type that is intended to hold the size of objects in bytes and the offsets of structure members. However, it appears that nothing prevents this type being as small as /unsigned char/. If so, the behaviour of /sizeof (char [UCHAR_MAX + 1])/ is unclear. The type /ptrdiff_t/ is a signed integral type that is intended to hold the difference between pointers into the same array object. However, it appears that nothing prevents this type being as small as /signed char/. If so, the behaviour of: char s [SCHAR_MAX + 1]; char *p = s + sizeof (s); p - s; is unclear. There are a number of possible approaches to these two problems. Detailed changes are given for each. Each proposal could make certain formerly strictly conforming programs require a diagnostic, but only when they use a very large object in some way. size_t ====== Option 1 -------- One possibility is to forbid the creation of objects whose size cannot be represented in a /size_t/. Quality of implementation would therefore force this type to be sufficiently large. Add to the Constraints of subclause 6.5: A declaration shall not specify an object whose size (in bytes) is greater than the maximum value of an object of type /size_t/. Option 2 -------- Alternatively, allow large objects to exist, but force a diagnostic if /sizeof/ is used on an object that's too big. Add a new Constraint to subclause 6.3.3.4: The /sizeof/ operator shall not be applied to an expression or to the name of a type such that the result is greater than the maximum value of an object of type /size_t/. Add a new Constraint to subclause 6.4: A constant expression shall not be derived from an expansion of the /offsetof/ macro where the offset of the structure member (in bytes) is greater than the maximum value of an object of type /size_t/. The latter constraint is not ideal, nor is it ideally placed. However, constraints are not found in clause 7. ptrdiff_t ========= Option 1 -------- As with /size_t/, we could prohibit arrays large enough to be a problem: Replace the Constraint of subclause 6.5.4.2 with: The expression delimited by [ and ] (which specifies the size of an array) shall be an integral constant expression that has a value greater than zero and less than or equal to the minimum of the absolute values of the minimum and maximum values of an object of type /ptrdiff_t/. Option 2 -------- Alternatively, since pointer subtraction is much more likely to be dynamic, it may suffice to allow the result to overflow. Change the last sentence of 6.3.6 paragraph 9 to read: Unless both pointers point to elements of the same array object, or one past the last element of the array object, or if the result is not representable as a value of type /ptrdiff_t/, the behaviour is undefined. [61] In this case, it may be worth putting a minimum range on /ptrdiff_t/. Append to subclause 7.1.6 () paragraph 2: The type /ptrdiff_t/ shall be capable of representing all values in the range -65535 to +65535 inclusive. [The numbers are taken from the "bytes in an object" translation limit.]