Help with migrating from 4.14 to 4.15

Well this is the umpteenth time migrating. It’s always fun but this time it seems something else is going on than normal deprecation and usage changes. Upon compiling my project I get a single error “error : Missing ‘;’ before ‘friend’”. This error occurs during the Unreal Header Tool. When I click it, it takes me to the first file it checks in my project and arbitrarily jumps to a structure I’ve defined in this static class file. Here’s a snippet from within that structure,


	friend FArchive& operator<<(FArchive& Ar, F3DARY& V)
	{
		return Ar << V.row << V.faces << V.numVerts;
	}

This code works fine in 4.14. Been using FArchive for awhile now and never had any issues. I also notice that my entire file is littered with intellisense lines, and since this occured during the UHT leads me to believe a header is messed up. When I scroll up to the top of my file I notice the first red line is the files generated.h. The generated header file is mising. I’ve checked in \Intermediate\Build\Win64\ and there is no Ue4Editor folder where the generated header files are usually kept. Don’t these file generate during the “Generate Project Files” option on the project file? If I delete the intermediate folder and retry this option to generate project files I see the intermediate folder is created, but no Ue4Editor folder within it, where the generated header files should be. So now I’m stuck. I’ve been reading about the new IWYU setup and part of me is wondering is this related? I’ve heard it’s optional, do I need to do something to opt out? Or should my project work as it did before without having to IWYU.

Thanks

You likely need to forward declare FArchive. Just add the following to where you have that operator defined:


class FArchive;

If you search through the code base, you’ll see this is a common paradigm a lot of classes had to use when moving to 4.15.

Let me add some detail here to where I’m at now with solving this problem. This is a header file where I’m declaring many structures in a row. Like this…


USTRUCT(BlueprintType)
struct FASTR
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY()
		TArray<int32> cells;
	FASTR(){}
	friend FArchive& operator<<(FArchive& Ar, FASTR& V)
	{
		return Ar << V.cells;
	}
};
USTRUCT(BlueprintType)
struct FBSTR
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY()
		TArray<FASTR> row;
	UPROPERTY()
		TArray<int32> faces;
	UPROPERTY()
		int32 numVerts;
	FBSTR()
	{
		numVerts = 0;
	}
	friend FArchive& operator<<(FArchive& Ar, FBSTR& V)
	{
		return Ar << V.row << V.faces << V.numVerts;
	}
};
USTRUCT(BlueprintType)
struct FCSTR
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY()
		TArray<FBSTR> ROW;
	FCSTR(){}
	friend FArchive& operator<<(FArchive& Ar, FCSTR& V)
	{
		return Ar << V.ROW;
	}
};

The error when compiling takes me to the friend FArhcive inside of FBSTR, stating “error : Missing ‘;’ before ‘friend’”. At this point my entire class file was littered with intellisense errors. Even though that error takes me to halfway, in the middle of a bunch of structure declarations (which all use FArchive). So I decided to comment out FBSTR structure and everything that used it (FCSTR), but only within this file, I just wanted to see what would happen. It compiled further AND, it created the Generated header files for my project (FINALLY). There was of course errors due to this structure not being defined. So now I uncommented the structure and tried compiling again since the header files were generated. I get the same error as before, but my intellesense has isolated around the structure in question.

So when you say forward declare you mean to put class FArchive at the top of my file by itself right (Sorry I’m self taught and not familiar with forward declarations, just googled it though). I tried what you recommended and it didn’t help. Is it possible I need to forward declare the structure itself? Thanks in advance…

Yes, so at the top of that code block you just showed, you should add the line I mentioned. If that didn’t work then you can try replacing that line with the following:


#include "Serialization/Archive.h"

(Again, at the top of your file) Which will definitely define the FArchive class for you so the compiler shouldn’t be complaining at that point.

I tried adding



#include "someheaders.h" //just showing where the headers are

class FArchive;
struct FASTR;
struct FBSTR;
struct FCSTR;

I tried just using the forward delcaration of FArchive, then just the Forward declarations of the structures, then both, and I also


#include "Serialization/Archive.h"

At the very top of my file (as the first include in my include list). I don’t know that it would be needed because I also have


#include "filemanagergeneric.h"

included which include #include “Serialization/Archive.h”. This was how I was using FArhcive to begin with. I really appreciate the help though, I’ve been stuck on this for 2 days now. Very frustrating.

Also as a side question, why would it allow me to get further in compiling by commenting out the FBSTR, and the FCSTR which uses the FBSTR, even though the first FASTR is basically the same (and there are other structures above that that are also using FArchive)? By “get further” I mean that it was able to get to the next part of compiling where it generates the generated header files stored here \Intermediate\Build\Win64\UE4Editor\Inc\ProjectName\

When the FBSTR and FCSTR are not commented out it never gets to the point where it generates the generated headers. It’s very bizarre. When I look inside the generated.h for this file I can see the first structure FASTR defined. I would manually define the other in the generated file but I’ve been told that is a bad idea. Plus there is some arbitrary number associated with the definitions in that file that I don’t know how to rationalize.

Can you post the errors you’re seeing in the output? Like the first 10 lines or so when the errors begin to show.

yeah, unfortunately VS decided it was going to recompile the engine too when I right-clicked ->build on the project, so I get to wait 20 minutes till it finishes.


1>------ Build started: Project: ShaderCompileWorker, Configuration: Development_Program x64 ------
1>Target is up to date
1>Deploying ShaderCompileWorker Win64 Development...
1>Total build time: 0.12 seconds (NoActionsToExecute executor: 0.00 seconds)
2>------ Build started: Project: KoreShanty, Configuration: Development_Editor x64 ------
2>Parsing headers for KoreShantyEditor
2>  Running UnrealHeaderTool "D:\GameDesign\KoreShanty-4.15 4.15\KoreShanty.uproject" "D:\GameDesign\KoreShanty-4.15 4.15\Intermediate\Build\Win64\KoreShantyEditor\Development\KoreShantyEditor.uhtmanifest" -LogCmds="loginit warning, logexit warning, logdatabase error" -Unattended -WarningsAsErrors
2>D:/GameDesign/KoreShanty-4.15 4.15/Source/KoreShanty/Public/ISC.h(703): error : Missing ';' before 'friend'
2>UnrealHeaderTool failed for target 'KoreShantyEditor' (platform: Win64, module info: D:\GameDesign\KoreShanty-4.15 4.15\Intermediate\Build\Win64\KoreShantyEditor\Development\KoreShantyEditor.uhtmanifest).
2>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.MakeFile.Targets(44,5): error MSB3075: The command "D:\GameDesign\UnrealEngine-4.15\Engine\Build\BatchFiles\Build.bat KoreShantyEditor Win64 Development "D:\GameDesign\KoreShanty-4.15 4.15\KoreShanty.uproject" -waitmutex" exited with code 5. Please verify that you have sufficient rights to run this command.
2>Done building project "KoreShanty.vcxproj" -- FAILED.
========== Build: 1 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========

And that error when double clicked leads to the middle of those three structures I posted above. If I comment this structure out, and the one below it, which uses it. Then It compiles further and generates the generated header files. Also, this is tested and works in 4.14 so it’s definitely related to 4.15 migration

Oh, duh. Turns out the compiler isn’t lying to you. Add a semicolon after the empty constructors you have defined:



FASTR(){}**;**
// ...
FCSTR(){}**;**



USTRUCT(BlueprintType)
struct FAry
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
		TArray<int32> cells;
	FAry()
	{
	};
	friend FArchive& operator<<(FArchive& Ar, FAry& V)
	{
		return Ar << V.cells;
	}
};
USTRUCT(BlueprintType)
struct F3DARY
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY()
		TArray<FAry> row;
	UPROPERTY()
		TArray<int32> faces;
	UPROPERTY()
		int32 numVerts;
	F3DARY()
	{
		numVerts = 0;
	};
	friend FArchive& operator<<(FArchive& Ar, F3DARY& V)
	{
		return Ar << V.row << V.faces << V.numVerts;
	}
};
USTRUCT(BlueprintType)
struct F4DARY
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY()
		TArray<F3DARY> ROW;	//UP TO DOWN
	F4DARY()
	{
	};
	friend FArchive& operator<<(FArchive& Ar, F4DARY& V)
	{
		return Ar << V.ROW;
	}
};

Ignore the slight name change, I have visual assist and I just did a rename on the structure (sometimes it clears up/ refreshes the intellesense lines). Anyhow, I made the changes by adding a “;” after the constructors, but now I get the error

“error : Unexpected ‘}’. Did you miss a semi-colon?”

Also, I never put a semicolon after empty constructors, is this accurate?

The semicolon after empty constructors may just be a habit thing for me, I’m honestly not sure what the standard says (my thought is it needs at least one semi-colon to know where the last statement ends, but I could be wrong - like I said, it’s just a habit for me at this point).

Try this out:



#include "Serialization/Archive.h"

USTRUCT(BlueprintType)
struct FAry
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	TArray<int32> cells;

	FAry() { };

	friend FArchive& operator<<(FArchive& Ar, FAry& V)
	{
		return Ar << V.cells;
	}
};

USTRUCT(BlueprintType)
struct F3DARY
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	TArray<FAry> row;

	UPROPERTY()
	TArray<int32> faces;

	UPROPERTY()
	int32 numVerts;

	F3DARY()
	{
		numVerts = 0;
	}

	friend FArchive& operator<<(FArchive& Ar, F3DARY& V)
	{
		return Ar << V.row << V.faces << V.numVerts;
	}
};

USTRUCT(BlueprintType)
struct F4DARY
{
	GENERATED_USTRUCT_BODY()
	
	UPROPERTY()
	TArray<F3DARY> ROW;	//UP TO DOWN

	F4DARY() { };

	friend FArchive& operator<<(FArchive& Ar, F4DARY& V)
	{
		return Ar << V.ROW;
	}
};


Negative on that last attempt. I don’t think it’s related to a header, at least in regards to it not understanding what an FArchive is, because there are many other structures I’ve defined in this file that all use FArchive the same way the structures in question do. Also I have #include “filemanagergeneric.h” included, which itself includes #include “Serialization/Archive.h”. This is how FArchive is being recognized. As for the semicolons I don’t think they make a difference. In all the other structures I’ve defined I never use a semicolon after the constructor (it could be bad habit that I don’t, but it has never caused a compile error). I’m so confused now. I don’t believe this is related to a syntax error. This project compiled fine (and still does) on the 4.14 engine version. So I think the syntax error would show up there if that was the case. I’m guessing its related to the new IWYU setup, but I don’t see any errors suggesting that it’s not understanding a type so that seems unlikely.

What really confuses me is the behavior I witnessed when I commented out the second two structures. It was able to get further in compiling, and only errored when those structures were referenced in other files using them. This allowed the compiler to get far enough to create the foo.generated.h files. When I look inside them I can see all my structures defined in the strange way those generated header files do. I’m tempted to manually enter the commented out structures but I don’t know much about how those files work. Something strange is going on…

Sometimes the unreal header tool will throw an error on X file on Y line with Z description but the problem is not there. The problem may be in other file and the unreal header tool drags that problem up to the point where it actually detects that something is wrong and fails. You should look for problems somewhere else in your code. Also make a full project clean (Delete binaries, intermediates folder, etc.) and try again.

So, when going from 4.14 to 4.15, by far the biggest issue is headers that used to be included through monolythic includes - now are absent. The big common “gotchas” are simply not including the Object macros for things like GENERATED_USTRUCT_BODY, etc:


#include "UObject/ObjectMacros.h"

and


#incldue "UObject/ScriptMacros.h"

If you’re using Blueprint exposed methods/types. You could try adding one or both of those and see if it fixes things. Also you may want to do a full clean/rebuild if you haven’t yet (I assumed you were if you didn’t see any generated output yet).

I tried adding those two headers, but then I realized that I shouldn’t need to because I have #include “object.h”. Here’s how my includes look


#include "object.h"
#include "runtime/headmounteddisplay/public/iheadmounteddisplay.h"
#include "runtimemeshcomponent.h"
#include "components/lightcomponent.h"
#include "kismet/kismetsystemlibrary.h"
#include "ufnblueprintfunctionlibrary.h"
#include "coremisc.h"
#include "filemanagergeneric.h"
#include "koremode.h"
#include "unrealnetwork.h"
#include "UObject/ObjectMacros.h"
#include "UObject/ScriptMacros.h"
#include "ISC.generated.h"

You can see the two you recommended there.

Yeah, I’m trying everything I can. I’ve deleted the intermediate folder, until recently there wasn’t much there anyhow, because it wouldn’t create the generated header files so nothing was really stored there. The binaries folder also did not exist until I commented out the two structures, and then it compiled further before encountering an error (due to the structures being commented out so other code that used them threw up errors). At least when I commented them out it did make it far enough in the build to actually create the generated header files and the binaries folder. I suspect this file is the first file that it checks so unless it’s related to the 2 plugins I use then I don’t think the error is elsewhere (though I’m exploring all options).

Try this



USTRUCT(BlueprintType)
struct F4DARY
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
        TArray<F3DARY> ROW;

};


FORCEINLINE FArchive operator << (FArchive& Ar, F4DARY& V)
 {
     Ar << V.ROW;
}


Ahh I was really hopeful with this one but no dice. The error just switches to “error : Missing ‘;’ before ‘FORCEINLINE’”