%% title = "how does GENERATED_BODY() work?"

% id = "01HV1DGFHMD7KNNX3FWS6R11SF"
- the `UCLASS()`, `USTRUCT()`, and other reflection macros - but especially the `GENERATED_BODY()` macro might seem a bit magical the first time you see them.

    % id = "01HV1DGFHM71ZD6CJY77N0PA8X"
    - the thing about it is that it defies the usual rules of how C++ macros work.
    let's have a look at it together.

% id = "01HV1DGFHM75BEC4B54MSBQ3P9"
- _what does it even expand to?_

    % id = "01HV1DGFHM2SAR1JMV8BAGDNE6"
    - try looking at what your IDE's autocomplete suggests -
    from a cursory glance at the symbols available in a `UCLASS()`-declared class, you will notice there are a few that are non-standard ones, such as `StaticClass()` or `Super`.
    this is what the `GENERATED_BODY()` macro ends up expanding to after all the preprocessing is done.

        % id = "01HV1DGFHMZ4F2DYDDJXXJXX63"
        - but the thing is that `Super` is a typedef to the parent class - how does it know the parent class without passing it in as a macro argument?

        % id = "01HV1DGFHMG2FFHTC9EA5NXB78"
        - and `StaticClass()` returns a different value for each class. this would require _knowing_ the class beforehand - how does it know?

% id = "01HV1DGFHMDFMWY2FWRHN3NGAX"
- the thing is - it doesn't. `GENERATED_BODY()` by itself is incredibly stupid:

```cpp
#define BODY_MACRO_COMBINE_INNER(A,B,C,D) A##B##C##D
#define BODY_MACRO_COMBINE(A,B,C,D) BODY_MACRO_COMBINE_INNER(A,B,C,D)
#define GENERATED_BODY(...) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_GENERATED_BODY);
```

let's disassemble it piece by piece.

    % id = "01HV1DGFHM4BW1FXVX3AMJYR91"
    - `BODY_MACRO_COMBINE` is just a macro combining four identifiers together. no magic here.

    % id = "01HV1DGFHM29ENZ6HE36B2SP92"
    - so `GENERATED_BODY` combines the identifiers `CURRENT_FILE_ID`, `_`, `__LINE__`, and `_GENERATED_BODY`.

        % id = "01HV1DGFHM8JH5RMTV79P8HRDV"
        + `CURRENT_FILE_ID` is a preprocessor macro defined by the UnrealBuildTool for each file.
        for simplicity's sake, let's assume it's the filename with dots replaced by underscores.
        for instance, `GameplayAbility_h`.

            % id = "01HV1DGFHM6XQ68XJPART8TND3"
            - the actual form it seems to take is `FID_{Path}` with `{Path}` being the file path relative to the project root directory, with slashes and dots replaced with underscores.
            for:

            ```
                Engine/Source/Runtime/Engine/Classes/Engine/Blueprint.h
            ```

            the file ID is:

            ```
            FID_Engine_Source_Runtime_Engine_Classes_Engine_Blueprint_h
            ```

            I haven't inspected the UnrealBuildTool/UnrealHeaderTool sources though, so there may be more to it.

        % id = "01HV1DGFHMVS11W47KWXJC7TY4"
        - `_` is just an underscore. nothing magical here.

        % id = "01HV1DGFHMPC27J2JN30PRGQSF"
        - `__LINE__` is a standard C++ macro which expands to the current line number.

        % id = "01HV1DGFHMAEZV26CE77X5AXYF"
        - and `_GENERATED_BODY` is just an identifier.

    % id = "01HV1DGFHM2Q8EC8EMKN0HMXTB"
    - therefore for a simple file, let's call it `MyClass.h`:

    ```cpp
    #pragma once

    #include "UObject/Object.h"

    #include "MyClass.generated.h"

    UCLASS()
    class UMyClass : public UObject
    {
        GENERATED_BODY()
    };
    ```

    after expanding the `GENERATED_BODY()`, we'll get this:

    ```cpp
    // -- snip --

    UCLASS()
    class UMyClass : public UObject
    {
        MyClass_h_10_GENERATED_BODY
    };
    ```

        % id = "01HV1DGFHM78BW738ENHCN0ASF"
        - and this identifier is declared as a macro in the UnrealHeaderTool-generated `MyClass.generated.h` -
        and expands to a bunch of declarations, including the declaration of `Super` and `StaticClass`, as well as constructors if they're not already declared.

            % id = "01HV1DGFHMFZNP6S3E1YNC8QH7"
            - you can even inspect the source code of `.generated.h` files yourself, by <kbd>Ctrl</kbd>+clicking on them (at least in Rider. I haven't tested Visual Studio.)

% id = "01HV1DGFHMP6ZP6N4WNWPTT04D"
- that's all there is to it.
incredibly simple, cursed as heck, yet super effective.