I know that the following is explicitly allowed in the standard:
int n = 0;
char *ptr = (char *) &n;
cout << *ptr;
What about this?>
The code int *ptr = (int *) &storage[0]; *ptr = 0;
causes undefined behaviour by violating the strict aliasing rule (C++14 [basic.lval]/10)
The objects being accessed have type char
but the glvalue used for the access has type int
.
The "dynamic type of the object" for a char
is still char
. (The dynamic type only differs from the static type in the case of a derived class). C++ does not have any equivalent of C's "effective type" either, which allows typed objects to be "created" by using the assignment operator into malloc'd space.
Regarding correct use of std::aligned_storage
, you're supposed to then use placement-new to create an object in the storage. The use of placement-new is considered to end the lifetime of the char
(or whatever) objects, and create a new object (of dynamic storage duration) of the specified type, re-using the same storage. Then there will be no strict aliasing violation.
You could do the same thing with the char array, e.g.:
alignas(int) char storage[sizeof(int)];
int *ptr = new(storage) int;
*ptr = 0;
cout << *ptr;
Note that no pseudo-destructor call or delete
is required for built-in type int
. You would need to do that if using a class type with non-trivial initialization. Link to further reading