Our project is currently updating to UE 5.5, and we have experienced an unexpected behavior change to CastChecked (Casts.h)
template <typename To, typename From>
FUNCTION_NON_NULL_RETURN_START
FORCEINLINE To* CastChecked(From* Src)
FUNCTION_NON_NULL_RETURN_END
{
static_assert(sizeof(From) > 0 && sizeof(To) > 0, "Attempting to cast between incomplete types");
// This code is removed
if (!Src)
{
return nullptr;
}
Since the below code ignores the optional argument CheckType
, this has the effect of causing a consitent crash when passing nullptr
to the CastChecked
function, even when ECastCheckedType::NullAllowed
is sent.
The behavior is different in the DO_CHECK
version above, which correctly allows nullptr
template <typename To, typename From>
To* CastChecked(From* Src, ECastCheckedType::Type CheckType)
{
static_assert(sizeof(From) > 0 && sizeof(To) > 0, "Attempting to cast between incomplete types");
if (Src)
{
To* Result = Cast<To>(Src);
if (!Result)
{
CastLogError(*GetFullNameForCastLogError(Src), *GetTypeName<To>());
}
return Result;
}
if (CheckType == ECastCheckedType::NullChecked)
{
CastLogError(TEXT("nullptr"), *GetTypeName<To>());
}
return nullptr;
}
We plan to change this code in our project to allow sending nulls when NullAllowed
is passed, but wanted to verify that the behavior change is intended, and that it is intended to be different between builds that have checks enabled and builds that do not (usually, Test/Shipping)