Catching exception with unreferenced local variable warning

11,115

Solution 1

You can #ifdef each catch line (very invasive) or add just a line in each catch block:

catch(const my_exception_type& e) {
    UNREFERENCED_PARAMETER(e);
    LOG("Exception %s", e.what());
    throw;
}

And the warning is gone. Or, you can #define MY_EXCEPTION_CATCH(...) to define the e parameter only in debug build.

Solution 2

You can mark the object as "used" by casting it to void. It has no influence on the generated machine code, but it will suppress the compiler warning.

try {
    // do some stuff
}
catch(const my_exception_type& e) {
    (void)e;
    LOG("Exception %s", e.what());
    throw;
}
Share:
11,115

Related videos on Youtube

Pupsik
Author by

Pupsik

Updated on September 16, 2022

Comments

  • Pupsik
    Pupsik over 1 year

    I've the following code:

    try {
        // do some stuff
    }
    catch(const my_exception_type& e) {
        LOG("Exception %s", e.what());
        throw;
    }
    

    The problem is that in debug build the LOG is defined as #define LOG(...) real_logger(...), but in release build is defined as #define LOG(...) \\ do nothing.

    Of course when I'm compiling my release code in Visual Studio, I'm getting the warning C4101: 'e' : unreferenced local variable.

    What is the best practice to handle exception logging without generation any unnecessary warnings?

    P.S
    I'm doing nothing with the exception except logging and re-throwing it.

  • Pupsik
    Pupsik almost 10 years
    #ifdef each catch line is something that I'm trying to ignore. What do you mean by adding e;? Can you elaborate?
  • Sga
    Sga almost 10 years
    if you add the line e; in each catch block, the compiler will consider that as a 'use' of the e variable... It's a trick to prevent the warning with the minimum code cluttering
  • Pupsik
    Pupsik almost 10 years
    It is interesting, there is another sample by Herb Sutter that is using template function: template<class T> void ignore( const T& ) { }. But are there other solutions?
  • Matthias247
    Matthias247 almost 10 years
    There are probably multiple ways to tell the compiler that an object is somehow used. The void cast is quite well known. QT even provides the macro Q_UNUSED(value) for that, which is defined as follows: #define Q_UNUSED(x) (void)x;
  • Clifford
    Clifford almost 10 years
    e=e is another common idiom.
  • Matthieu M.
    Matthieu M. almost 10 years
    @Clifford: unfortunately, this may trigger a self-assignment that the compiler cannot optimize away (for user-defined types).
  • Matthieu M.
    Matthieu M. almost 10 years
    @Pupsik: This is the best option in general, and another is using a macro, because it explains what is going on. In your case, modifying the LOG macro to avoid this; you could define LOG in release to cast to void (each argument).
  • Clifford
    Clifford almost 10 years
    @MatthieuM. Your code just threw an exception, optimisation is the least concern at that point perhaps?
  • Matthieu M.
    Matthieu M. almost 10 years
    @Clifford: Not necessarily, if your code is too slow on the error path, then an onslaught of "wrong" inputs may cause a DoS. Thus, at least it should be as fast as the regular path.
  • Clifford
    Clifford almost 10 years
    @MatthieuM. Goot point - worth highlighting the idiom then just so the unwary (like me perhaps) know why they should not do it! - it is common in C but should not be copied in C++.