c++compilationmacros

Create C++ macro which defines a compiler variable and calls method


I am trying to create a compiler macro in C++ that will define a (compiler) variable and then call a C++ method. For example, if I have this in my C++ code:

TL_CLI_ADD_EXIT_CODE(123,"SOMENAME","Description of code")

I want the compiler to expand it to:

#define EXITCODE_SOMENAME   123
addExitCode(123,"SOMENAME","Description of code");

The closest I've gotten for code is:

// Macro to concatenate EXITCODE_ prefix with the number
#define TL_CLI_CONCAT_EXITCODE(number) EXITCODE_##number

// Macro to create a new exit code definition
#define TL_CLI_ADD_EXIT_CODE(c,n,d) \
  #define TL_CLI_CONCAT_EXITCODE(n) c \
  addExitCode(c,\"n\",d);

Is what I'm trying to do even possible? I seem to cycle between various errors including "'#' is not followed by a macro parameter". Can someone advise what is wrong?


Solution

  • This is C++, try to avoid MACROs when you can. Often there is some kind of constexpr approach possible, like this :

    #include <string_view>
    #include <vector>
    #include <iostream>
    #include <format>
    
    struct ExitCode
    {
        int code;
        std::string_view name;
        std::string_view description;
    
        // implicit conversion to int (for interop with other API's)
        operator int() const noexcept
        {
            return code;
        }
    };
    
    std::ostream& operator<<(std::ostream& os, const ExitCode& err)
    {
        os << std::format("Error : {}, description = {}", err.name, err.description);
        return os;
    }
    
    //-----------------------------------------------------------------------------
    
    static constexpr ExitCode EXITCODE_SOMENAME{123,"SOMENAME","Description of code"};
    
    // return a ref, all data will be put in by compiler (no dynamic mem alloc)
    const ExitCode& SomeFunction()
    {
        return EXITCODE_SOMENAME;
    }
    
    int main()
    {
        auto& retval = SomeFunction();
        std::cout << retval << "\n";
        return retval; // implicit conversion to int here
    }