Why macros like USTURCT() can't be wrapped by custom macros

I’m going to use a macro to create multiple reflected structs, but the builds all fail!

#define DEFINE_RESOURCE_LOGIN_REQUEST(StructName, DataType) \
USTRUCT()\
struct StructName \
{ \
	GENERATED_BODY()\
	int32 code; \
	FString msg; \
	TArray<DataType> data; \
};

DEFINE_RESOURCE_LOGIN_REQUEST(FLoginRequest,FRequestData_Login)

It looks perfect, but it compiles with Error C4430:

0>ResourceStruct_HTTP.h(171): Error C4430 : Missing type specifier - assumed to be int. Note: C++ does not support the default int.

I’ve also included the file for reflections:

#include "CoreMinimal.h"
#include "ResourceStruct_HTTP.generated.h"

Can anyone help with the answer? Thank you for your answer.

Not sure what datatype is in your project is it a custom struct? This compiles fine:

USTRUCT()
struct FDataType
{
	GENERATED_BODY()	
};

#define DEFINE_RESOURCE_LOGIN_REQUEST(StructName, DataType) 
USTRUCT()
struct FStructName
{ 
	GENERATED_BODY()
	int32 code; 
	FString msg; 
	TArray<FDataType> data; 
};

DEFINE_RESOURCE_LOGIN_REQUEST(FLoginRequest, FRequestData_Login)

Try sticking with Unreal’s naming convention. Structs start with F (your compiler will warn you)

3dRaven, the code you shared is different from Bssnake. See Bssnake uses "" (in the end of lines) that allows declaring a macro on multiple lines of a source file.

@Bssnake, your code doesn’t compile because it is not supposed to work. The issue in code lies in the improper use of Unreal Engine’s reflection system macros and how the Unreal Header Tool (UHT) processes them.

Reflection Macros are different from C++ Preprocessor Macros. UHT scans for these reflection macros to generate crucial boilerplate code for Unreal’s reflection system and object-processing systems BEFORE the C++ preprocessor does his job. So, nothing under “#define” is expanded at the moment of UHT work.
So, these macros only function correctly when they are directly present in the source code, as UHT does not expand or interpret custom preprocessor macros.

In other words, when UHT process such a code it does not evaluate or expand macros:

#define DEFINE_USTRUCT(Name) \
USTRUCT() \
struct Name { GENERATED_BODY(); };

DEFINE_USTRUCT(FMyStruct);

it only sees this

DEFINE_USTRUCT(FMyStruct);

It has no knowledge of what DEFINE_USTRUCT means because the macro expansion is handled later by the C++ preprocessor, which UHT does not interact with

Hope that explains the issue.