Wrapping U... macros with preprocessor directives

Hello,

I would like to declare a UPROPERTY that is only accessible in Development builds for debug purposes, e.g:

#if !UE_BUILD_SHIPPING
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Debug")
	bool bDrawBordersAtRuntime;
#endif //!UE_BUILD_SHIPPING

but this throws following UHT error at compile time:

Error: 'UPROPERTY' must not be inside preprocessor blocks, except for WITH_EDITORONLY_DATA

And after looking for this error in source, it seems like all U… macros cannot be wrapped by the preprocesor macro (UhtTokenBufferReader.cs):

if (localValueSpan.CompareTo("UPROPERTY", StringComparison.Ordinal) == 0 ||
	localValueSpan.CompareTo("UCLASS", StringComparison.Ordinal) == 0 ||
	localValueSpan.CompareTo("USTRUCT", StringComparison.Ordinal) == 0 ||
	localValueSpan.CompareTo("UENUM", StringComparison.Ordinal) == 0 ||
	localValueSpan.CompareTo("UINTERFACE", StringComparison.Ordinal) == 0 ||
	localValueSpan.CompareTo("UDELEGATE", StringComparison.Ordinal) == 0 ||
	localValueSpan.CompareTo("UFUNCTION", StringComparison.Ordinal) == 0)
{
	this.LogError($"'{localValueSpan.ToString()}' must not be inside preprocessor blocks, except for WITH_EDITORONLY_DATA");
}

This appears to be a pretty big limitation. What are the reasons for said limitation?
As I understand, the whole module can be excluded from the shipping build, so it’s a bit strange that some of the functions/properties cannot be excluded (but there is probably a good reason for that).

Are there any alternatives that I can use in this case?

Thanks!

Okey, after thinking about this problem a bit I started to realize that there is indeed a lot of reasons explaining why this wouldn’t work - e.g. this would break a lot of stuff in Blueprints, and would be generally hard to manage there.

There is a DevelopmentOnly meta specifier for UFunction (ObjectMacros.h):

/// [PropertyMetadata] For functions that should be compiled in development mode only.
DevelopmentOnly, 

So I can probably solve my exact case in the following way:

#if !UE_BUILD_SHIPPING
	bool bDrawBordersAtRuntime;
#endif //!UE_BUILD_SHIPPING

	UFUNCTION(BlueprintCallable, Category = "Debug", meta = (DevelopmentOnly))
	void SetDrawBordersAtRuntime(bool bNew)
	{
#if !UE_BUILD_SHIPPING
		bDrawBordersAtRuntime = bNew;
#endif //!UE_BUILD_SHIPPING
	}

	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Debug", meta = (DevelopmentOnly))
	bool GetDrawBordersAtRuntime()
	{
#if !UE_BUILD_SHIPPING
		return bDrawBordersAtRuntime;
#endif //!UE_BUILD_SHIPPING
		return false;
	}

Not very elegant but should work just fine.

Leaving my question open in case someone has a better idea.