Compiler or UHT not checking everything

I enabled the compiler to throw errors on shadow variable errors:

<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
  <BuildConfiguration>
    <ProcessorCountMultiplier>1</ProcessorCountMultiplier>
    <bShadowVariableErrors>true</bShadowVariableErrors>
  </BuildConfiguration>
</Configuration>

After making this change and hitting F5 there are no compilation errors. Then I added a new UPROPERTY and initialized it in the cpp file and then suddenly that file and another file (which remained completely unchanged by me) threw shadow variable compiler errors. The code that that the shadow-errors applied to was not changed between the working compile and the one that threw errors.

So why did the compiler not throw me this error when I pressed F5 the first time? Well… I assume that this is related to this: Object finder: cannot convert 'UStaticMesh ' to 'UObject ' - Programming & Scripting - Epic Developer Community Forums

And why does it also not compile anymore when I hit ctrl+z until it reverts back to the original state? It still does not compile even though the code is now EXACTLY THE SAME as when it used to compile. BUT when I use SourceControl to revert the exact same change, then it compiles.

and How can a forward declaration cause "undefined" - C++ - Epic Developer Community Forums and some other posts that I forgot.

I believe that the compiler/UHT don’t check files that were already compiled successfully previously and stores/caches those in some way. Files are probably grouped together for compilation and if even one of those files is changed (even if it’s a useless comment that was added), the whole group get’s recompiled or at least re-checked. That would explain why ctrl+z spamming the code back to the original state were it used to compile doesn’t compile.

This mechanic may be good for saving on compilation time for big projects but it also causes the compiler to not throw errors when it should. And sometimes I even see old files that should no longer compile (but they do as long as I never touch them nor the ‘group’ they belong to anymore) due to missing includes or more graves mistakes from me. But in the past I got them to compile and then they are never checked anymore by the compiler/UHT?

I’m posting this in the bug reports section. My apologies if this is intended behavior but then please let me know why. So far nobody could answer it. I have heard various wild theories but nobody could tell me what exactly is happening.

Note that I am posting this as an answer because of the comment-character-limitation.

I just had another compiler error on this line:

StaticMeshComp->SetStaticMesh(ULib::CreateObject<UStaticMesh>("/Game/Assets/AmmoSet/Models/cal9mm/cal9mm_PaperBoxOpen"));

error C2664: ‘void
ConstructorHelpers::ValidateObject(UObject
*,const FString &,const TCHAR *)’: cannot convert argument 1 from
‘UStaticMesh *’ to ‘UObject *’

So I pressed F12 on UStaticMesh and ended up in EngineType.h on line 2522:

UPROPERTY(EditAnywhere, Category=BuildSettings)
class UStaticMesh* DistanceFieldReplacementMesh;

Erm… Yeah… That kinda explains… First of all this is a forward declaration (which causes the compiler error) and secondly that is not the one from Engine/MeshComponent.h that I was expecting.

Now here comes the interesting part. This class compiles and uses the proper UStaticMesh (inherits from the same base class as the other one):

#include "PU9mm.h"
#include "Lib.h"

APU9mm::APU9mm()
{
	StaticMeshComp->SetStaticMesh(ULib::CreateObject<UStaticMesh>("/Game/Assets/AmmoSet/Models/cal9mm/cal9mm_PaperBoxOpen"));

	PickupText = NSLOCTEXT("Default", "9mm Ammo", "9mm Ammo");
	AmmoType = EItemType::Ammo9mm; // TODO: is the AmmoType variable really required?
	ItemCategory = EItemCategory::Default;
	ItemStackInfo.ItemType = AmmoType;
	LoadIcon("/Game/UI/Textures/InventoryIcons/Ammo_9mm");
	ItemName = NSLOCTEXT("Default", "9mm Ammo", "9mm Ammo");
}

And this one does not and uses the one from EngineType.h:

#include "Stone.h"
#include "Lib.h"

AStone::AStone()
{
	StaticMeshComp->SetStaticMesh(ULib::CreateObject<UStaticMesh>("/Game/Assets/AmmoSet/Models/cal9mm/cal9mm_PaperBoxOpen"));

	//PickupText = NSLOCTEXT("Default", "Stone", "Stone");
	//ItemCategory = EItemCategory::Default;
	//ItemStackInfo.ItemType = EItemType::Stone;
	//LoadIcon("/Game/UI/Textures/InventoryIcons/Ammo_9mm");
	//ItemName = NSLOCTEXT("Default", "Stone", "Stone");
}

So 2 classes that aside from their name are exactly identical (okay I outcommented some unrelated lines for testing purposes in the second one but it made no difference). One compiles and one does not.

But it get’s even worse. After adding the include include “Engine/StaticMesh.h” manually to the one that didn’t compile and then removing that include again still caused the second one to magically compile (yes without the include this time). Yes my code is EXACTLY the same as before when it did not compile but now it uses the proper UStaticMesh include… Erm… There has got to be some kind of caching bug somewhere… I mean, sometimes I just have files that pseudo-randomly give compiler errors (without being changed) completely out of the blue and they ask for includes that they never required before (and now apparently) vice versa as well. And on top of that other classes that are nearly identical don’t require those include (but may do so at a later time for unknown reasons).

The workaround is obviously to use the specific includes and force the UHT/compiler to use the proper ones (which might be considered better code anyway). But why it sometimes uses the one from include A and sometimes the one from include B for the exact same class… No idea… It could be intended behavior but its’ weird. And it also (a bit) beats the purpose of including

Hi Napoleonite,

Sorry for the delay in responding to your post. Are you still having trouble with this issue? If so, we have a new process for reporting Engine bugs. If you are still having trouble with this, please fill out the forum on our Report a Bug page with as much information as you have available.