Date: Mon, 21 Sep 2026 10:11:14 +0200
If anything we need *more* casts, not less. Current casts are still a
grouping of intents where the user intends one, but the actual execution
might be another.
Take for example dynamic_cast<B*>(A*) - one of the most restricted already,
working only from polymorphic types to other polymorphic types. But even
then, it offers multiple casts:
- Upcasting, where the conversion works statically and the compiler knows
it's just a static_cast already
- Downcasting, where the compiler knows that the target type derives from
the source type and which path it should take
- Crosscasting, where the compiler does not know of any relation between
the two types, but where the cast can still succeed because of a struct C :
A, B {}; in some invisible TU elsewhere.
Writing this as upcast<B*>(A*), downcast<B*>(A*) or crosscast<B*>(A*) makes
explicit what result the user is expecting and what checks the compiler can
already do. The compiler can then also mark the translation unit as
ill-formed when the intended cast does not work - for example, this would
enable the compiler to break compilation on a dynamic downcast if the
inheritance hierarchy is changed so that users already know it'll never
downcast, instead of trying a crosscast anyway and always failing.
But we're not proposing this right now.
Going to *fewer* casts with even wider interpretations is a horrible idea
for C++ as it makes it less able to discern what you're trying to do and
more likely to accidentally compile something that could statically be
known to be broken.
On Mon, Sep 21, 2026 at 9:55 AM Jan Schultke via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
>
> On Mon, 21 Sept 2026 at 09:45, Liam Graham via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> We have reinterpret_cast, const_cast, dynamic_cast, static_cast.
>>
>> What does the CPU do? Nothing. It doesn't care
>>
>
> It does care. If you have a pointer to a base class subobject and cast
> that to a derived type, i.e. cast<Derived*>(&my_base_object):
>
> - reinterpret_cast might downcast "too far" because it casts to the
> most derived object for polymorphic classes, or do something else
> nonsensical if you're not dealing with polymorphic classes
> - static_cast will downcast properly, but is unchecked and results in
> UB if you don't actually have a surrounding derived object
> - dynamic_cast will perform a runtime check for whether the cast is
> valid and give you a null pointer if it's not
> - std::bit_cast will reinterpret the pointer bits unchanged, whatever
> that does
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
grouping of intents where the user intends one, but the actual execution
might be another.
Take for example dynamic_cast<B*>(A*) - one of the most restricted already,
working only from polymorphic types to other polymorphic types. But even
then, it offers multiple casts:
- Upcasting, where the conversion works statically and the compiler knows
it's just a static_cast already
- Downcasting, where the compiler knows that the target type derives from
the source type and which path it should take
- Crosscasting, where the compiler does not know of any relation between
the two types, but where the cast can still succeed because of a struct C :
A, B {}; in some invisible TU elsewhere.
Writing this as upcast<B*>(A*), downcast<B*>(A*) or crosscast<B*>(A*) makes
explicit what result the user is expecting and what checks the compiler can
already do. The compiler can then also mark the translation unit as
ill-formed when the intended cast does not work - for example, this would
enable the compiler to break compilation on a dynamic downcast if the
inheritance hierarchy is changed so that users already know it'll never
downcast, instead of trying a crosscast anyway and always failing.
But we're not proposing this right now.
Going to *fewer* casts with even wider interpretations is a horrible idea
for C++ as it makes it less able to discern what you're trying to do and
more likely to accidentally compile something that could statically be
known to be broken.
On Mon, Sep 21, 2026 at 9:55 AM Jan Schultke via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
>
> On Mon, 21 Sept 2026 at 09:45, Liam Graham via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> We have reinterpret_cast, const_cast, dynamic_cast, static_cast.
>>
>> What does the CPU do? Nothing. It doesn't care
>>
>
> It does care. If you have a pointer to a base class subobject and cast
> that to a derived type, i.e. cast<Derived*>(&my_base_object):
>
> - reinterpret_cast might downcast "too far" because it casts to the
> most derived object for polymorphic classes, or do something else
> nonsensical if you're not dealing with polymorphic classes
> - static_cast will downcast properly, but is unchecked and results in
> UB if you don't actually have a surrounding derived object
> - dynamic_cast will perform a runtime check for whether the cast is
> valid and give you a null pointer if it's not
> - std::bit_cast will reinterpret the pointer bits unchanged, whatever
> that does
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2026-09-21 08:11:30
