This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-11


2814. Alignment requirement of incomplete class type

Section: 7.6.1.9  [expr.static.cast]     Status: NAD     Submitter: Janet Cobb     Date: 2023-10-20

Consider:

  struct X;       // declared, but not defined

  int i;
  X* p = static_cast<X*>(static_cast<void*>(&i));

Is the value of p unspecified per 7.6.1.9 [expr.static.cast] paragraph 14?

A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, ...

Is that a case where implementations have to possibly pessimize a use of an undefined class, because a later definition can have the worst possible properties? Such a situation can also occur for pointer-to-members of undefined classes.

CWG 2023-12-15

The resulting pointer value should be unspecified if T is incomplete.

CWG 2024-03-18

CWG decided to reverse direction here and to constrain implementations, not programs.

Proposed resolution [SUPERSEDED]:

Change in 7.6.1.9 [expr.static.cast] paragraph 14 and add bullets as follows:

A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory , T is complete, and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, ...

Possible resolution:

Change in 7.6.1.9 [expr.static.cast] paragraph 14 and add bullets as follows:

A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory , T is complete anywhere in the program, and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, ...

CWG 2024-06-28

It is understood that a pointer value of type T* may point to an object whose type is unrelated to T. (Any access through such a pointer value is undefined behavior.) However, C++ maintains the invariant that the address represented by a pointer value of type T* is always suitably aligned for a T. The rule that is the concern of this issue ensures the invariant holds even when values of type T* are obtained by casting, and not by taking the address of an object. For the latter case, the invariant holds because an object cannot exist unless its storage is aligned suitably.

The rule that is the concern of this issue therefore primarily constrains user programs, not implementations. It is unclear which "pessimizations" are expected from casting to a type whose alignment requirements are unknown at the point of the cast. Note that the resulting unspecified pointer value may be an invalid pointer value (6.8.4 [basic.compound]), which is essentially useless. Note also that incomplete class types may have (minimum) alignment requirements, because an alignment-specifier can appear in an elaborated-type-specifier.