Suppose I have:
char * bufPtr = ...; // points into a char array with at least sizeof(void *) chars remaining
void *ptr1 = ...;
void *ptr2;
Assuming that bufPtr is properly aligned, are the lines
*(void **)bufPtr = ptr1; // (1)
ptr2 = *(void **)bufPtr; // (2)
legal? I know that char * can alias anything, but does that allowance go the other direction?
UPDATE: The codebase I'm working on is in C, so that's the language I'm most interested in (if I can only get the answer for one). I thought C and C++ would be similar in this regard, but maybe I was wrong about that.
TLDR:
No. You can not treat
[un[signed]] chardata as any other type without violating strict aliasing.However, untyped memory is different. You can treat untyped memory a new type via assignment.
Full Answer:
Given
char *bufptr, casting to avoid **withpotentially violates 6.3.2.3 Pointers, paragraph 7:
Note that the pointer does not have to be dereferenced to invoke undefined behavior - merely creating a misaligned pointer is enough to invoke undefined behavior.
Assigning value to the dereferenced pointer with
may or may not violate strict aliasing, depending on what
bufptractually points to.From comments moved to chat, the memory has been characterized as "untyped". In that case, such an assignment does not violate strict aliasing.
However, the history of the use of that memory may impact whether or not the memory remains untyped. See Does C strict aliasing make untyped static memory pools impossible?. Note in particular this answer:
I'd compile the allocator code with
-fno-strict-aliasingand-fno-ipa-strict-aliasingif using GCC, or an equivalent if not. See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fstrict-aliasing.