Date: Fri, 24 Feb 2023 03:42:17 +0200
On Thu, 23 Feb 2023 at 22:14, Lénárd Szolnoki via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> I know you are not proposing this, but just for the record: Such an
> empty_class_downcast would still subvert aliasing. While compilers
> still have to treat a base pointer and the derived pointer as
> potentially aliasing, they can still assume that a derived pointer and
> an other derived pointer of a different type can't alias. Example:
>
> struct Base {
> int i;
> };
>
> struct Derived1 : Base {};
> struct Derived2 : Base {};
>
> void foo(Derived1* ptr1, Derived2* ptr2) {
> ptr1->i += ptr2->i;
> ptr1->i += ptr2->i;
> /* compilers currently are allowed to transform this into:
> ptr1->i += 2*ptr2->i;
> */
> }
>
> gcc seems to do this transformation:
> https://godbolt.org/z/M9q5EMacE
>
> So if you have a pointer to Base, it is still unsafe to "empty class
> downcast" it to Derived1, as the actual complete type might be derived
> from Derived2 and this might subvert aliasing down the line.
Thanks, good point.
I am indeed not suggesting that we make any language change here, a
class hierarchy where every class
is constructible from a pointer/reference to the
originally-desired-base-class, and where you add a utility
function that converts the base of the hierachy to any derived class
in the hierarchy will suffice fine for
the uses depicted, and more. The hierarchy's classes have non-owning
semantics like the suggested
pointers resulting from a cast would, you just use them by value
everywhere. Shazam:
https://wandbox.org/permlink/D1LrNyCu4bthAP4P
<std-proposals_at_[hidden]> wrote:
> I know you are not proposing this, but just for the record: Such an
> empty_class_downcast would still subvert aliasing. While compilers
> still have to treat a base pointer and the derived pointer as
> potentially aliasing, they can still assume that a derived pointer and
> an other derived pointer of a different type can't alias. Example:
>
> struct Base {
> int i;
> };
>
> struct Derived1 : Base {};
> struct Derived2 : Base {};
>
> void foo(Derived1* ptr1, Derived2* ptr2) {
> ptr1->i += ptr2->i;
> ptr1->i += ptr2->i;
> /* compilers currently are allowed to transform this into:
> ptr1->i += 2*ptr2->i;
> */
> }
>
> gcc seems to do this transformation:
> https://godbolt.org/z/M9q5EMacE
>
> So if you have a pointer to Base, it is still unsafe to "empty class
> downcast" it to Derived1, as the actual complete type might be derived
> from Derived2 and this might subvert aliasing down the line.
Thanks, good point.
I am indeed not suggesting that we make any language change here, a
class hierarchy where every class
is constructible from a pointer/reference to the
originally-desired-base-class, and where you add a utility
function that converts the base of the hierachy to any derived class
in the hierarchy will suffice fine for
the uses depicted, and more. The hierarchy's classes have non-owning
semantics like the suggested
pointers resulting from a cast would, you just use them by value
everywhere. Shazam:
https://wandbox.org/permlink/D1LrNyCu4bthAP4P
Received on 2023-02-24 01:42:30