What does "rvalue used as lvalue" mean?

I’m trying to write a function in my game mode that checks to ensure that key logic actors have been spawned in the level, and spawns them if they don’t exist:

	UPROPERTY(EditAnywhere)
	TSubclassOf<AActor> HUDManagerBlueprint; //Developer manually points this to the HUD Manager BP in editor
    AHUDManager* HUDManager;

if (HUDManager == nullptr){
		AActor* tempActor = GetWorld()->SpawnActor(HUDManagerBlueprint, &FVector(0, 0, 0));
		HUDManager = Cast<AHUDManager>(tempActor);
	}

This looks right to me, but it produces a compiler warning that I’ve never seen before: “error C4238: nonstandard extension used : class rvalue used as lvalue”. Is this related to my spawning objects in the game mode instead of an actor? Because I’ve used almost this exact syntax in other classes, and I’ve never seen this particular error.

AActor* tempActor = GetWorld()->SpawnActor(HUDManagerBlueprint, &FVector(0, 0, 0));
You’re creating a temporary FVector and using its address. You should create a vector variable and reference that instead.

const FVector vec(0, 0, 0);
AActor* tempActor = GetWorld()->SpawnActor(HUDManagerBlueprint, &vec);

Or in this case, you can also use the static FVector::ZeroVector instance.

AActor* tempActor = GetWorld()->SpawnActor(HUDManagerBlueprint, &FVector::ZeroVector);

Ooh you are absolutely right, thank you! I was so fixated on the cast being right, I never even looked twice at the vector :slight_smile:

Hey this worked for me, but why does it work?

// rvalue used as lvalue error

	const FTransform* FlagSpawnTransform = &GetTransform();
	World->SpawnActor(ACTFFlag::StaticClass(), FlagSpawnTransform);

// compiled

	const FTransform FlagSpawnTransform = GetTransform();
	World->SpawnActor(ACTFFlag::StaticClass(), &FlagSpawnTransform);

GetTransform returns something by-value, and you’re taking a pointer to that return value. That means you’re taking a pointer to a temporary that will immediately go out-of-scope.

It works in the second case since you’re keeping the value alive by copying/moving/eliding it into your copy, and then taking a pointer to that copy instead.

That makes total sense, thank you so much for the explanation.

ComPtr texture;
CheckHR(device->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(format, width, height, 1, 0, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ), NULL, &texture));

Hey, bro. why dose it work?