void* has always the size of the CPU register, for efficiency, configuring it to a smaller size is a compiler concept, that is, instead of using the natural architecture instruction, the compiler issues a smaller register instruction.
^^^ in 64bit Arch use a ^^^ 32bit void*
>Point 2) All data pointers have the same size >and alignment. So if you
>apply "sizeof" or "alignof" to any data pointer, >you always get the
>same answer. Same representation too, >obviously.
Currently they have all the same alignment.
The only difference is when you want to read the pointer value,
if it is of size 2, use a CPU register of size 2
If it is of size 4, use a CPU register of size 4
...etc
>Point 3) No loss of precision when converting >between pointer types
>whose pointed-to type have differing >alignment requirements.
It is already the case. The compiler is not allowed to fiddle with the value's bits no matter what alignment the pointed-to type requires.
It is the responsibility of the programmer to observe type aliasing rules, otherwise UB.
>Specifically:
>Even though the memory address of a >'double' will always be a multiple
>of 8, I want the lower 3 bits of the pointer to >still retain their
>value, so that the following is possible:
Yes, it is currently preserved.
Hana Dusíková is using this guarantee for her pointer tagging proposal.
> Line 1: char c;
> Line 2: double *p = static_cast<double*> (static_cast<void*>(&c));
> Line 3: char *p2 = static_cast<char*>(static_cast<void*>( p ));
> Line 4: *p2 = 'h';
This snippet is totally fine and it is equivalent to:
char c;
char* p = &c;
*p = 'h';
No UB observed.
>Looking at Line #2, I could see that a >compiler could possibly
>zero-out the lower 3 bits of the value of 'p', >but I want this to be
>forbidden in C++26.
No it could not, and it is not allowed. The only thing you will MAYBE get is a misaligned pointer to a double memory location, and you should not dereference that pointer, because of aliasing incompatibility otherwise UB.
Try the following code:
#include <stdio.h>
int main()
{
char arr[8];
double* ptr = static_cast<double*>(static_cast<void*>(arr+3));
printf("%p", ptr);
return 0;
}
// possible output
// 0x7fff934a9d83
^^ misaligned for a double.
>This would be a major simplification of data >pointers in C++, and it
>would aid in relocating objects into unaligned >memory (for example
>std::basic_string<char32_t> which contains a >pointer pointing into its
>own internal buffer).
I didn't understand this statement.