Is Unreal's IsValid() meant to always be used instead of a c++ nullptr check, or is it optional based on the situation?

Hi,

I just wonder as a general rule in C++ for UE4, when checking for a nullptr, is it ok to just a standard C++ check, or should you always use Unreal’s IsValid (which also checks if object is pending kill)?

In my game no objects get destroyed during game play, only when you change map.
As far as I know Blueprint always uses IsValid, which is why I’m asking. Is it better to just be on the safe side, since I assume checking pending kill is a fast operation? (I’m more used to C++ than I am UE4).

if(Actor) vs.

if(IsValid(Actor))

2 Likes

There are also IsValidLowLevel() and IsValidLowLevelFast() methods in UObject class. They are usefull if you need class to be valid for sure and you can’t pass any invalid behaviour.
I used to check on nullptr before, but recently tend to use Unreal methods, since it’s never in tick and I don’t think it’ll make that much of a difference performance wise but definitely safer

Hi,

first off, thank you for responding :slight_smile:

I know about these additional IsValid checks, the reason I’m ignoring those in my question is that they are unreal-functions, just more complex versions, using more operations, and should probably only be used in special cases. Basically, if unreal always wanted you to use IsValidLowLevel() instead of IsValid(), the extra functionality within IsValidLowLevel() would just be in IsValid() instead, if that makes sense?

BUT since a normal nullptr check is native to c++, Unreal cannot remove that function.
So maybe I should formulate my question more like “Is Unreal’s IsValid() meant to always be used instead of a c++ nullptr check, or is it optional based on the situation?”

I guess sort of like the way Static_Cast<>() was created to always be used instead of c-style casting, regardless of the situation.

I doubt it will make much performance difference either, I’m mostly curious as to what people think is best practice :slight_smile:

From looking at Unreal source code, they definitely don’t use IsValid() all the time, ex:

void AActor::AttachToComponent(USceneComponent* Parent, const FAttachmentTransformRules& AttachmentRules, FName SocketName)
{
	if (RootComponent && Parent)
	{
		RootComponent->AttachToComponent(Parent, AttachmentRules, SocketName);
	}
}

oddly a few functions below that you have this:

void AActor::ForEachAttachedActors(TFunctionRef<bool(class AActor*)> Functor) const
{
	if (RootComponent != nullptr)
	{
...

And the syntax keeps swapping throughout Actor.cpp
So I guess their different coders don’t really have any standard in syntax they agree on either 0:

Well, IsValid () checks, if an object is non-null and not marked ready for being garbage collected during the next garbage collection cycle.

Yes, I noticed that too, I guess it’s because engine is being developed and updated for so long.

Regarding your question, I’d say (and this is more of an opinion of mine, so don’t take it as granted), if you use simple nullptr check you could end up in a situation when object is for example prepared for garbage collection (like you called destroy method or something) but still not null and IsValid() check will prevent you from using it in that condition.

1 Like

I am not sure if anyone is going to stumble across this, but I think IsValid() should be used on objects that have a UPROPERTY() over them and hence is being garbage collected, and you should be using nullptr checks if you are sure that the object that the pointer points to is not being garbage collected.

5 Likes