Date: Wed, 21 Jan 2026 12:57:11 +0000
Before I begin, I realise that static_cast can cause UB with
intrinsics, for example:
char a;
double &d = *static_cast<double*>( static_cast<void*>(&a) );
d = 0.0;
But in this post I'm talking specifically about classes. We can use
'static_cast' to convert from a derived class to a base:
Base *b = static_cast<Base*>( &derived );
or more simply:
Base *b = &derived;
If you imagine this as a UML class diagram, you'll have a box for
Base, and then below it you'll have a box for Derived. You're
converting from Derived to Base, so the movement is going upwards, and
so we call it an upcast.
Converting from Base to Derived is called a downcast, and it can cause UB:
struct Base { int a; };
struct Derived : Base { int b; };
Base var;
Derived &derived = static_cast<Derived&>( var );
derived.b = 666;
This should never have been made possible with 'static_cast' -- there
should have been a different kind of cast operator for this purpose.
When I'm using 'static_cast' with classes in my own code, in order to
avoid a downcast, I use my own 'static_upcast' defined as follows:
template<class Derived, class Base>
concept derived_fromCV = is_base_of_v<Base, Derived> &&
is_convertible_v<Derived*, Base*>;
template<class To, class From>
requires is_lvalue_reference_v<To> && (!is_reference_v<From>)
&& derived_fromCV< From, remove_reference_t<To> >
[[nodiscard]] constexpr To static_upcast(From &arg) noexcept
{
return static_cast<To>(arg);
}
This prevents me from doing a dodgy down-cast, which is a necessary
precaution in my implementation of chimeric_ptr. Note that I use my
own 'derived_fromCV' instead of 'std::derived_from' to avoid a
const/volatile violation.
static_cast should never have been allowed to perform downcasts, and
in order to deal with this issue, I think the following should happen:
C++29: Using static_cast for downcasts should be marked
deprecated, and a compiler warning should be issued wherever
static_cast is used for purpose, and the compiler should provide the
alternative 'static_downcast'.
C++32: static_cast forces a compiler error when used for a
downcast, and so you must use static_downcast
intrinsics, for example:
char a;
double &d = *static_cast<double*>( static_cast<void*>(&a) );
d = 0.0;
But in this post I'm talking specifically about classes. We can use
'static_cast' to convert from a derived class to a base:
Base *b = static_cast<Base*>( &derived );
or more simply:
Base *b = &derived;
If you imagine this as a UML class diagram, you'll have a box for
Base, and then below it you'll have a box for Derived. You're
converting from Derived to Base, so the movement is going upwards, and
so we call it an upcast.
Converting from Base to Derived is called a downcast, and it can cause UB:
struct Base { int a; };
struct Derived : Base { int b; };
Base var;
Derived &derived = static_cast<Derived&>( var );
derived.b = 666;
This should never have been made possible with 'static_cast' -- there
should have been a different kind of cast operator for this purpose.
When I'm using 'static_cast' with classes in my own code, in order to
avoid a downcast, I use my own 'static_upcast' defined as follows:
template<class Derived, class Base>
concept derived_fromCV = is_base_of_v<Base, Derived> &&
is_convertible_v<Derived*, Base*>;
template<class To, class From>
requires is_lvalue_reference_v<To> && (!is_reference_v<From>)
&& derived_fromCV< From, remove_reference_t<To> >
[[nodiscard]] constexpr To static_upcast(From &arg) noexcept
{
return static_cast<To>(arg);
}
This prevents me from doing a dodgy down-cast, which is a necessary
precaution in my implementation of chimeric_ptr. Note that I use my
own 'derived_fromCV' instead of 'std::derived_from' to avoid a
const/volatile violation.
static_cast should never have been allowed to perform downcasts, and
in order to deal with this issue, I think the following should happen:
C++29: Using static_cast for downcasts should be marked
deprecated, and a compiler warning should be issued wherever
static_cast is used for purpose, and the compiler should provide the
alternative 'static_downcast'.
C++32: static_cast forces a compiler error when used for a
downcast, and so you must use static_downcast
Received on 2026-01-21 12:57:25
