Avoiding unused variables warnings when using assert() in a Release build

前端 未结 16 1696
隐瞒了意图╮
隐瞒了意图╮ 2020-12-05 09:10

Sometimes a local variable is used for the sole purpose of checking it in an assert(), like so -

int Result = Func();
assert( Result == 1 );
<
相关标签:
16条回答
  • 2020-12-05 09:46

    Certainly you use a macro to control your assert definition, such as "_ASSERT". So, you can do this:

    #ifdef _ASSERT 
    int Result =
    #endif /*_ASSERT */
    Func();
    assert(Result == 1);
    
    0 讨论(0)
  • 2020-12-05 09:49

    With recent C++, I would just say:

    [[maybe_unused]] int Result = Func();
    assert( Result == 1 );
    

    See https://en.cppreference.com/w/cpp/language/attributes/maybe_unused for more details on this attribute.

    Compared with the (void)Result trick, I like it better, because you directly decorate the variable declaration, you don't just add something as an afterthought.

    0 讨论(0)
  • 2020-12-05 09:53

    We use a macro to specifically indicate when something is unused:

    #define _unused(x) ((void)(x))
    

    Then in your example, you'd have:

    int Result = Func();
    assert( Result == 1 );
    _unused( Result ); // make production build happy
    

    That way (a) the production build succeeds, and (b) it is obvious in the code that the variable is unused by design, not that it's just been forgotten about. This is especially helpful when parameters to a function are not used.

    0 讨论(0)
  • 2020-12-05 09:55

    You could use:

    Check( Func() == 1 );
    

    And implement your Check( bool ) function as you want. It may either use assert, or throw a particular exception, write in a log file or to the console, have different implementations in debug and release, or a combination of all.

    0 讨论(0)
  • 2020-12-05 09:55

    You should move the assert inside the function before the return value(s). You know that the return value is not an unreferenced local variable.

    Plus it makes more sense to be inside the function anyway, because it creates a self contained unit that has its OWN pre- and post-conditions.

    Chances are that if the function is returning a value, you should be doing some kind of error checking in release mode on this return value anyway. So it shouldn't be an unreferenced variable to begin with.

    Edit, But in this case the post condition should be X (see comments):

    I strongly disagree with this point, one should be able to determine the post condition from the input parameters and if it's a member function, any object state. If a global variable modifies the output of the function, then the function should be restructured.

    0 讨论(0)
  • 2020-12-05 09:56

    I wouldn't be able to give a better answer than this, that addresses that problem, and many more:

    Stupid C++ Tricks: Adventures in assert

    #ifdef NDEBUG
    #define ASSERT(x) do { (void)sizeof(x);} while (0)
    #else
    #include <assert.h>
    #define ASSERT(x) assert(x)
    #endif
    
    0 讨论(0)
提交回复
热议问题