Title
Alignment requirement of incomplete class type
Status
nad
Section
7.6.1.9 [expr.static.cast]
Submitter
Janet Cobb

Created on 2023-10-20.00:00:00 last changed 3 weeks ago

Messages

Date: 2024-06-29.11:03:16

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.

Date: 2024-06-29.11:03:16

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, ...
Date: 2024-03-20.14:10:31

CWG 2024-03-18

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

Date: 2024-03-20.14:10:31

CWG 2023-12-15

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

Date: 2023-12-16.00:18:01

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.

History
Date User Action Args
2024-06-29 11:03:16adminsetmessages: + msg7764
2024-06-29 11:03:16adminsetstatus: ready -> nad
2024-06-26 19:00:47adminsetstatus: tentatively ready -> ready
2024-06-14 20:48:28adminsetstatus: review -> tentatively ready
2024-03-20 14:10:31adminsetmessages: + msg7649
2024-03-20 14:10:31adminsetmessages: + msg7648
2023-12-16 00:18:01adminsetmessages: + msg7556
2023-12-16 00:18:01adminsetstatus: open -> review
2023-10-20 00:00:00admincreate