Silence warnings about unused variables / functions at the point of their conditionally compiled use

So, in the doctest (my testing framework), the user can disable all tests by specifying the DOCTEST_CONFIG_DISABLE identifier, which makes the following code and macros:

TEST_CASE("name") {
    int a = 5;
    int b = 6;
    CHECK(a == b);
}

      

after the preprocessor, the following is included:

template<typename T>
void some_anon_func_123() {
    int a = 5;
    int b = 6;
}

      

this means that the self-writing test case becomes an unexplored template function and the macro CHECK()

(which functions like an if statement that checks a condition) into a no-op - like this:

#define CHECK(x) ((void)0) // if disabled

      

However, if the user has such testing code in a separate function, for example:

static int g() {
    std::cout << "called!" << std::endl;
    return 42;
}

static void f() {
    int a = 5;
    CHECK(a == g());
}

TEST_CASE("name") {
    f();
}

      

then there will be warnings for unused functions and unused variables. doctest prides itself on having 0 warnings even at the most aggressive levels , so this is unacceptable.

I tried the trick ((void) ...)

by passing a macro argument to it like this:

#define CHECK(x) ((void)(x))

      

and that did turn off the warnings (at least for a

and g()

), but code is still being generated for this statement - if I call the function f()

from mine main()

, I see called!

it printed in the console. This is undesirable as I want to compile as quickly as possible when test cases and assertions are disabled from the assembly (using the DOCTEST_CONFIG_DISABLE identifier). If a user has 100,000 assertions and assemblies with them disabled, he doesn't want all unnecessary codegins and compile time for macros to be disabled ( CHECK()

one).

__attribute__((unused))

should be used at the point of a variable declaration - I cannot insert it into a macro CHECK()

(or I don't know ...).

Not sure _Pragma()

if it can help - and even if it might - it has been known to have problems with GCC:

Is there a solution to my problem - for example, is it possible to pass an expression to some template or something ...? (Requires C ++ 98)

I explained my problem in agonizing detail just because I was often accused of the XY problem ...

EDIT:

The C ++ 11 solution is okay too - some C ++ 11 features started conditionally part of the library anyway ...

+3


source to share


1 answer


So, you want to "lie" to the compiler that you are using a function that you are not actually calling. So how do you use a piece of code without executing it?

It looks like the only thing that works on all popular compilers is a C ++ 11 based solution - a lambda that is never called:

#define CHECK(x) [&](){ ((void)(x)); }

      

If you absolutely need a C ++ 98 solution that sizeof

will also work on many compilers, MSVC is a notable exception:



#define CHECK(x) sizeof(x)

      

MSVC will still warn about unclaimed functions in the expression x

.

I guess you can use a combination of the two for maximum coverage.

+1


source







All Articles