Sporadic UHT issue detecting new files

This isn’t going to be easy to repro, but it’s now happened to me a couple of times. So far I believe it has only occurred when working with an engine source build.

issue is this: sometimes, having added a header file to project containing a definition of a new reflected type, UHT will fail to recognise it and generate an ‘Unrecognized type’ error at a line in a file which references it. For example, I add following file:

// MyNewType.h
#pragma once
#include "MyNewType.generated.h"

USTRUCT(BlueprintType)
struct FMyNewType
{
...
};

And modify an existing file to reference it:

// MyExistingType.h
#pragma once
#include "MyNewType.h"
#include "MyExistingType.generated.h"

UCLASS()
class UMyExistingType: public UObject
{
GENERATED_BODY()

public:
UPROPERTY(EditAnywhere)
FMyNewType NewTypeProp;

...
};

I then (once in a while) get an ‘Unrecognized type’ error at line declaring property. No amount of cleaning project or regenerating project files seems to help when this happens.

Something that may help track this down. In latest case, file containing property did not directly include newly added file. It included it via an intermediate header file, which (not sure if this is relevant or not) was a standard header - no reflection/.generated include. include paths themselves were correct - if I commented out UPROPERTY line above actual member variable, everything built fine. Yet I solved the ‘Unrecognized type’ error by adding a direct include to new header file in header where I declared property.

Unfortunately I don’t think issue is a simple one. I have a parallel group of classes which I had already added and have no issues with despite not including header directly. Also, first time I encountered this issue I spent hours stepping through UHT code in debugger, only for it finally to start working on one run through without me apparently changing anything. I suspect perhaps UHT may be caching some information from previous runs to avoid regenerating everything from scratch each time (?) and perhaps issue is related to this.

Apologies for wall of text for what is not a pressing issue, but perhaps it will help someone track it down.


EDIT: Adding code demonstrating current situation


// TheTypeFile.h
#pragma once

#include "TheTypeFile.generated.h"

// NOTE: Header name and type name are not same.
// May be irrelevant, anyway at this point renaming it to be same makes no difference.
USTRUCT()
struct FTheType
{
  GENERATED_BODY()
  ...
};

// TheIntermediate.h
#pragma once

#include "TheTypeFile.h"

// TheReflectedIntermediate.h
#pragma once

#include "TheTypeFile.h"
#include "TheReflectedIntermediate.generated.h"

USTRUCT()
struct FAnyReflectedType
{
  GENERATED_BODY()
};

// TheContainer.h

#pragma once

#include "TheIntermediate.h"
// NOTE: Uncomment either of these and error disappears
// #include "TheTypeFile.h"
// #include "TheReflectedIntermediate.h"
#include "TheContainer.generated.h"

UCLASS()
class UTheContainer: public UObject
{
  GENERATED_BODY()

public:
  UPROPERTY()
  FTheType TheProperty;  // UHT ERROR HERE: Unrecognized type 'FTheType'
};

Hi ,

Thanks for report! I’ve assigned a member of our team to look at this, and they’ll post here if they have any other questions for you.

Hi

You mention adding this .h file, but how are you adding it? Are you creating a new .h in Visual Studio or are you adding a new C++ class through Unreal Editor? It seems like something that would only happen (Not as though it should of course) when adding code files without using Class Wizard in Editor.

Hi .

You are correct. I do vast majority of my work in C++ in VS, for me it is much faster to add files directly to VS project than adding code via UE4 editor.

I did a little more testing and confirmed one of my suspicions above. Currently for one of my properties I can build without problems if I include type’s header file directly. I just tested and found that it also works if I include it not directly, but indirectly through another reflected header file. But if I make include via an intermediate header that is not reflected, I get UHT error. I’ve added more code to question to demonstrate.

Unfortunately though, as stated I also have other instances where a file is being included indirectly through an unreflected header, yet it works as expected. Hence my suspicion that issue’s reproduction is dependent on some UHT cached state.

Let me know if I can provide any more information. I don’t envy your task in attempting to reproduce this though!

Bit more info for you. It does appear there is an issue with UHT not recursively parsing #include files if intermediate includes do not contain reflected types. I think I’ve discovered reason this behaviour didn’t seem very predictable.

It seems UHT builds a list of reflected headers/types as it goes, but doesn’t remove from this list after processing each header. So results depend on order in which it processes files - not sure if this is just alphabetical or something else. So if, taking my example above, TheTypeFile.h gets processed before UHT comes to TheContainer.h, there won’t be an error since it has already discovered FTheType. So in that case, any problem with recursive lookup won’t show up. If on other hand UHT comes to TheContainer.h first, then recursive lookup needs to find FTheType or we get an ‘Unrecognized type’ error.

Hi ,

I must have missed it first time I read your question but it seems like issue is that header file you’re creating with Visual Studio is being placed into Intermediate folder. Intermediate folder is a folder that is generated by GenerateProjectFiles and any code in there will be ignored by this process. This could also cause issues if you ever need to transfer your project as deleting Intermediate folder saves a lot of space, since it can be regenerated easily. I would suggest moving any code files created this way to Source folder under either Public or Private so that they are recognized.

I hope this helps.

Hi .
Nope, all my headers are in correct location, in source directory.

Where I’ve used term intermediate above, I meant in sense of indirectly including a header file through a chain of #includes (see code added to question). So if A includes B and B includes C, then A is including C indirectly via an ‘intermediate’ file (B).

Sorry for confusion, I guess it wasn’t a very good choice of word to use.

Hello ,

I apologize for previous confusion, it was partially my fault as well. I’ve reproduced issue that you’re experiencing using code that you provided. As such, I’ve also placed a bug report in for issue. For your reference, bug number is UE-19283. Hopefully this will be fixed soon, although unfortunately I do not have any workarounds that I can provide in meantime aside from making any files like this into reflected headers as you have already pointed out.

Thank you for your help reproducing this issue and have a nice day,

After looking into issue further and looking at what it would take to fix this issue, it’s been decided that this is an issue that we won’t be fixing. reason why is due to compile times. If we were to make UHT parse all headers instead of only reflected ones, it would have a detrimental effect on compile times. This is something that we would like to do in future but it will be quite some time before that happens.

Understood, thanks for looking into this.

I think it would be worth documenting this limitation, it’s not all that difficult to come up against, but easy to waste a lot of time trying to work out.