Clarification about IsValid() and nullptr safety

I was hoping to get a little clarification about best practices regarding safety checks for nullptrs. This is a function which returns the current game session:

if(IsValid(GetWorld()) && (IsValid(GetWorld()->GetAuthGameMode())))
{
	return Cast<AE6KGameSession>(GetWorld()->GetAuthGameMode()->GameSession);
}

return nullptr;

My question is, is the first IsValid(GetWorld()) statement necessary for nullptr safety, or will the following (IsValid(GetWorld()->GetAuthGameMode()) statement automatically check for the world before attempting to access the game mode through the world? In other words, in the event that GetWorld() returned a nullptr, would the program throw an exception on the second statement if the first statement wasn’t there?

*(And yes, I realize this specific example is largely redundant in practice, but I wanted to get clarification on this for cases when it might be more important!)

**(I’m also aware that creating an object of the type to be returned and accessing the next function from that object can also be considered a better practice here, but that can rapidly get verbose in many cases.)

will the following (IsValid(GetWorld()->GetAuthGameMode()) statement automatically check for the world before attempting to access the game mode through the world?

No. IsValid(GetWorld()->GetAuthGameMode()) will attempt to call the function GetAuthGameMode() from UWorld* to, in this case, pass it into IsValid(). It will not stop when GetWorld() returns a nullptr since nullptr is a valid return value for pointers (this is fine as the alternative is a crash). If UWorld* is a nullptr it’ll crash when calling GetAuthGameMode(), since GetAuthGameMode() is not a function of nullptr basically.

That said, your && operator will break as soon as anything is false, and it reads left to right.

So lets say IsValid(GetWorld()) is false. The && operator breaks and the if statement is done before it even considers the next evaluation, since you will never reach the inner scope anyway.

if your if statement was something like if(false && true) then it would actually never reach the ‘&& true’ part since the first evaluation was false.

Same goes for the || operator. If the first evaluation is true, then it’s not going to check for any further evaluations, since you’ll always reach the inner scope.

You can (and should) imagine your code as:

if(IsValid(GetWorld()) {
  if(IsValid(GetWorld()->GetAuthGameMode()) {
    return // your code
  }
}

So you have to check each step, you have to check GetWorld() first and yes it feels a little redundant, but there’s no performance issues because of how logical operators work.

A little programming tip is to invert your condition statements where possible to avoid nesting. Video example (Not C++ but the idea remains the same): https://www.youtube.com/watch?v=CFRhGnuXG-4

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.