I'm using a logging module that can have reporting enabled/disabled at runtime. Calls generally go something like:
WARN(
"Danger Will Robinson! There are "
+ boost::lexical_cast<string>(minutes)
+ " minutes of oxygen left!"
);
I'm using an inline function for WARN, but I'm curious as to how much optimization is going on behind the scenes -- evaluation of the arguments throughout the entire program would be costly. The WARN
function goes something like this:
bool WARNINGS_ENABLED = false;
inline void WARN(const string &message) {
if (!WARNINGS_ENABLED) {
return;
}
// ...
}
Given that constructing the string argument has no side-effects, will the compiler optimize it out? Is a certain level of optimization required (-Ox
in g++
for some x
)?
If you need to be able to selectively enable and disable the warnings at run-time, the compiler will not be able to optimize out the call.
What you need is to rename your function to WARN2
and add a macro something like:
#define WARN(s) do {if (WARNINGS_ENABLED) WARN2(s);} while (false)
This will prevent the evaluation of s at run-time unless you have warnings enabled.
The do-while stuff is a trick that allows it to be used anywhere in the code (naked statement, statement within a braced if-block, statement within an unbraced if-block, braced and unbraced while statements and so on).
You can check what GCC/G++ do by using the -S option. This will output the code before it actually gets assembled – see gcc(1).
GCC and G++ more or less behave the same in this case. So I first translated the code into C to make some further tests:
char WARNINGS_ENABLED = 0;
inline void WARN(const char* message) {
if (!WARNINGS_ENABLED) {
return;
}
puts(message);
}
int main() {
WARN("foo");
return 0;
}
run gcc -O3 -S file.c and look into the output file 'file.s'
You will see that GCC didn't remove anything!
That's not what you asked for, but in order to give the compiler the opportunity to optimize that code out, you would have to make WARNINGS_ENABLED constant. An alternative is to make it static and not changing the value within that file. But: making it static has the side-effect that the symbol gets not exported.
static const char WARNINGS_ENABLED = 0;
inline void WARN(const char* message) {
if (!WARNINGS_ENABLED) {
return;
}
puts(message);
}
int main() {
WARN("foo");
return 0;
}
GCC then completely cleans up the code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With