Date: Tue, 28 Jan 2025 14:04:44 +0100
I think the low bits are always safe from being dropped, because if any change touchs them, due to alignment constraint, it will affect the whole byte they are part of, which by consequence alters the whole pointer value.Sent from my Galaxy
-------- Original message --------From: Tiago Freire <tmiguelf_at_[hidden]> Date: 1/28/25 11:50 AM (GMT+01:00) To: std-proposals_at_[hidden] Cc: organicoman <organicoman_at_[hidden]> Subject: Re: [std-proposals] Make all data pointers intercompatible
I think you forgot about the alignment.
Even if objects are the same size, and compilers can handle pointers to unknown types. That doesn't mean that in contexts where the type is know that the compiler can't just simply drop the low bits from the pointer if they are irrelevant due
to alignment. And surely it will not mean that you would be able to dereference from and unrelated type that does not satisfy the same alignment requirements.
From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of organicoman via Std-Proposals <std-proposals_at_[hidden]>
Sent: Tuesday, January 28, 2025 11:13:10 AM
To: Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Cc: organicoman <organicoman_at_[hidden]>
Subject: Re: [std-proposals] Make all data pointers intercompatible
Frederick,
sizeof(void*) >= sizeof(char*)
sizeof(void*) >= sizeof( any class pointer )
This is more accurate than equality.
void* should have a large enough size to hold the representation of any pointer value without alteration.
Also if for expl:
sizeof(char*) != sizeof(T*)
Strict aliasing rule mandate that to be able to cast between these two types safely
you must fulfill 3 conditions:
1- sizeof(T*) >= sizeof(char*)
2- T and char are compatible types
3- no const violation.
Compatible types means, the data is aligned at a memory boundary where the value can be read naturally.
So if you are in doubt if two pointer types U and T are not the same size then it should be safe to add an intermediary cast to void* before casting to the target pointer type.
T* t;
void* v = static_cast<void*>(t);
U* u = static_cast<U*>(v);
But dereferencing the pointer is UB, unless the 3 conditions above are met.
Regards
Sent from my Galaxy
-------- Original message --------
From: Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Date: 1/28/25 10:42 AM (GMT+01:00)
To: std-proposals_at_[hidden]
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: Re: [std-proposals] Make all data pointers intercompatible
Not entirely sure where this thread has ventured off to, but let me
get back to what I was talking about (i.e. the size of pointers).
Given the following translation unit:
class MyClass;
MyClass *my_global_variable;
The compiler doesn't know the alignment requirements of MyClass. For
instance it might be:
struct MyClass { char c; };
or it could be:
struct MyClass { long double f; };
Therefore I think we can make the following assertion:
sizeof(void*) == sizeof(char*) == sizeof( any class pointer )
This means that we should be able to do the following:
class SomeClass;
void *GiveMeBackTheArgumentUnchanged(void *const arg)
{
SomeClass *const p = static_cast<SomeClass*>(arg);
return p;
}
The above code should work fine on every C++ compiler because a
SomeClass* should be the same as a void*.
The only complication though is that the following pointers could
still be smaller than a void*:
short*
int*
long*
long long*
float*
double*
long double*
But since there's no compiler alive today that actually does that, I
think C++26 should mandate that all data pointers are the same size
and representation.
-------- Original message --------From: Tiago Freire <tmiguelf_at_[hidden]> Date: 1/28/25 11:50 AM (GMT+01:00) To: std-proposals_at_[hidden] Cc: organicoman <organicoman_at_[hidden]> Subject: Re: [std-proposals] Make all data pointers intercompatible
I think you forgot about the alignment.
Even if objects are the same size, and compilers can handle pointers to unknown types. That doesn't mean that in contexts where the type is know that the compiler can't just simply drop the low bits from the pointer if they are irrelevant due
to alignment. And surely it will not mean that you would be able to dereference from and unrelated type that does not satisfy the same alignment requirements.
From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of organicoman via Std-Proposals <std-proposals_at_[hidden]>
Sent: Tuesday, January 28, 2025 11:13:10 AM
To: Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Cc: organicoman <organicoman_at_[hidden]>
Subject: Re: [std-proposals] Make all data pointers intercompatible
Frederick,
sizeof(void*) >= sizeof(char*)
sizeof(void*) >= sizeof( any class pointer )
This is more accurate than equality.
void* should have a large enough size to hold the representation of any pointer value without alteration.
Also if for expl:
sizeof(char*) != sizeof(T*)
Strict aliasing rule mandate that to be able to cast between these two types safely
you must fulfill 3 conditions:
1- sizeof(T*) >= sizeof(char*)
2- T and char are compatible types
3- no const violation.
Compatible types means, the data is aligned at a memory boundary where the value can be read naturally.
So if you are in doubt if two pointer types U and T are not the same size then it should be safe to add an intermediary cast to void* before casting to the target pointer type.
T* t;
void* v = static_cast<void*>(t);
U* u = static_cast<U*>(v);
But dereferencing the pointer is UB, unless the 3 conditions above are met.
Regards
Sent from my Galaxy
-------- Original message --------
From: Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Date: 1/28/25 10:42 AM (GMT+01:00)
To: std-proposals_at_[hidden]
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: Re: [std-proposals] Make all data pointers intercompatible
Not entirely sure where this thread has ventured off to, but let me
get back to what I was talking about (i.e. the size of pointers).
Given the following translation unit:
class MyClass;
MyClass *my_global_variable;
The compiler doesn't know the alignment requirements of MyClass. For
instance it might be:
struct MyClass { char c; };
or it could be:
struct MyClass { long double f; };
Therefore I think we can make the following assertion:
sizeof(void*) == sizeof(char*) == sizeof( any class pointer )
This means that we should be able to do the following:
class SomeClass;
void *GiveMeBackTheArgumentUnchanged(void *const arg)
{
SomeClass *const p = static_cast<SomeClass*>(arg);
return p;
}
The above code should work fine on every C++ compiler because a
SomeClass* should be the same as a void*.
The only complication though is that the following pointers could
still be smaller than a void*:
short*
int*
long*
long long*
float*
double*
long double*
But since there's no compiler alive today that actually does that, I
think C++26 should mandate that all data pointers are the same size
and representation.
-- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-01-28 13:04:55