Coding standards

GDK for Unreal C++ coding standards

In general, we follow the Coding Standard (Unreal documentation) set out by Epic. This page highlights some additions to Epic's guidelines.

  • Avoid assignments in if statements unless the variable is declared in the statement.
    It's good practice to limit the lifetime of a variable using the scope. For instance if a variable is only used within an if statement, then its lifetime is cleanly managed using the following approach:
if (APawn* Pawn = Cast<APawn>(Actor))
{
//do something with the Pawn variable
}

This is safe as the compiler will generate a C2143 compiler error if a comparison is accidentally added:

if (APawn* Pawn == Cast<APawn>(Actor))
{
// will generate a C2143
}

However, if the variable is declared earlier in the outside scope and cannot be contained within the scope of the statement, then we should avoid using assignments in the statement:

For example, prefer:

APawn* Pawn = Cast<APawn>(Actor);
if (Pawn != nullptr)
{
//do something with the Pawn variable
}

to:

APawn* Pawn;

if(Pawn = Cast<APawn>(Actor)) //NOOOO
{

}
  • Wrap native C++ classes/structs in the improbable namespace. For any object that is not tagged with USTRUCT or UCLASS, we should use the namespace improbable to avoid name collision. The classes that are wrapped in namespaces should not use the U, F or A prefixes to make it easy to distinguish these from the Unreal classes.
  • Separate your includes into alphabetized groups, depending on the include file origin. Where possible, group your includes in the following order:
    1. GDK includes
    2. Engine includes
    3. Other includes, such as Worker SDK files, or C library files.

There are two reasons to use this order:

  • It reduces the chance that you will accidentally omit necessary includes.
  • You should place GDK includes before any engine includes because GDK files can include engine files, but not vice versa.

If you follow these ordering rules, then you are more likely to get useful compiler errors during development that tell you about missing includes. If you don't follow these rules, then you will see fewer errors in the short term, but might cause ambiguous errors in the future due to missing includes.

Example

For example, suppose you have the following files:

- Engine/A.h
- GDK/B.h
- GDK/C.h

GDK/B.h relies on some Engine/A.h exports, but doesn't include Engine/A.h. Consider the following two scenarios.

Scenario A
In this scenario, you don’t follow the recommended order. Instead, you set up your includes as follows:

//FILE: GDK/C.h
#include Engine/A.h
#include GDK/B.h

Note: GDK/B.h does not include Engine/A.h.

Outcome: The project compiles. If GDK/C.h is the only file that includes GDK/B.h, then the compiler might not object that GDK/B.h does not include Engine/A.h.

However, if another developer later includes GDK/B.h in any file without including Engine/A.h first, then the compilation will fail, and the reason for the failure might not be clear.

Scenario B
In this scenario, you follow the recommended order. You set up your includes as follows:

//FILE: GDK/C.h
#include GDK/B.h
#include Engine/A.h

Note: GDK/B.h does not include Engine/A.h.

Outcome: You receive a compiler error stating that GDK/B.h misses the Engine/A.h include. You avoid the later problem where compilation fails without a clear reason.


2020-09-22 Page updated with editorial review: clarification to rules about include order
2020-09-17 Page updated with editorial review: added rules about include order

Updated about a year ago


Coding standards


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.