Search code examples
c++parametersmacrosparameter-passingprecompile

Can I Conditionally Use More Than 1 Argument?


So this code works well as an example:

#ifdef DEBUG
#define DECLARE_DEBUG_PARAM(x) x
#define PASS_DEBUG_PARAM(x) x
#else
#define DECLARE_DEBUG_PARAM(x) void
#define PASS_DEBUG_PARAM(x)
#endif

int foo(DECLARE_DEBUG_PARAM(const bool param)) {
#ifdef DEBUG
    if(param) {
        cout << "DEBUG true\n";
    } else {
        cout << "DEBUG false\n";
    }
#else
    cout << "RETAIL\n";
#endif
}

int main() {
    foo(PASS_DEBUG_PARAM(true));
}

Live Example

But I want to use this for a second parameter, for example: int foo(const int param1, DECLARE_DEBUG_PARAM(const int param2)) Obviously that doesn't work for my current definition of DECLARE_DEBUG_PARAM, I get the error:

error: invalid use of type void in parameter declaration

Is there some noop parameter type that I can use which would allow this?


Solution

  • To quote the C++ FAQ:

    Because #define macros are evil in 4 different ways: evil#1, evil#2, evil#3, and evil#4. Sometimes you should use them anyway, but they’re still evil.

    It doesn't make sense to use a macro here. It's simply #ifdefing out code, but requiring the user to look that up. A much better approach would simply be to use an #ifdef:

    int foo(
    #ifdef DEBUG
            const bool param
    #endif
           );
    int foo(const int param1
    #ifdef DEBUG
            , const int param2
    #endif
           );
    

    And to call do the same thing:

    foo(
    #ifdef DEBUG
        true
    #endif
       );
    foo(13
    #ifdef DEBUG
        , 42
    #endif
       );
    

    This code can be a bit choppy for functions taking a small number of arguments and may be laid out with a #else if that is considered more readable:

    #ifdef DEBUG
        int foo(const bool param);
    #else
        int foo();
    #endif
    #ifdef DEBUG
        int foo(const int param1, const int param2);
    #else
        int foo(const int param1);
    #endif
    

    The same thing may be done for the calls:

    #ifdef DEBUG
        foo(true);
    #else
        foo();
    #endif
    #ifdef DEBUG
        foo(13, 42);
    #else
        foo(13);
    #endif