Catching exception with unreferenced local variable warning
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;
}
Related videos on Youtube
Pupsik
Updated on September 16, 2022Comments
-
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 almost 10 years
#ifdef
eachcatch
line is something that I'm trying to ignore. What do you mean by addinge;
? Can you elaborate? -
Sga almost 10 yearsif you add the line
e;
in each catch block, the compiler will consider that as a 'use' of thee
variable... It's a trick to prevent the warning with the minimum code cluttering -
Pupsik almost 10 yearsIt 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 almost 10 yearsThere 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 macroQ_UNUSED(value)
for that, which is defined as follows:#define Q_UNUSED(x) (void)x;
-
Clifford almost 10 years
e=e
is another common idiom. -
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. 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 defineLOG
in release to cast tovoid
(each argument). -
Clifford almost 10 years@MatthieuM. Your code just threw an exception, optimisation is the least concern at that point perhaps?
-
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 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++.