Description
Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [intro.object], [basic.lval], [expr.assign], [diff.expr]
Link to reflector thread (if any):
Issue description:
In C23, writing to an allocated memory region can change the effective type of an object.
Per WG14 N3220 6.5.1 p6:
- The effective type of an object for an access to its stored value is the declared type of the object, if any.84) If a value is stored into an object having no declared type through an lvalue having a type that is not a non-atomic character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using
memcpy
ormemmove
, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.
The rule is recently expanded to cover byte arrays in C2y via WG14 N3254, and thus becomes more close to the implicit object creation rule in C++.
Consider the following example:
#include <stdlib.h>
int main() {
union U {
int m;
float n;
};
void* p = malloc(sizeof(U));
if (!p)
return 0;
*(int*)p = 0; // #1
*(float*)p = 0.0f; // #2
free(p);
}
In C, #2
changes the effective type of the object in the allocated storage, and thus has well-defined behavior. However, in C++, there's no way to make the execution well-defined, because the lifetime for the int
and float
objects at the same address can't simultaneously start, and #2
can't change the active member of a union ([class.union.general] p5) even if a union object is implicitly created.
I think we should either mention such incompatibility in [diff.expr] (if it's intentional) or eliminate it by specifying some kinds of assignment can re-create objects in certain memory regions.
Suggested resolution: