How can I check if a code block is optimized away, without looking at the compiled code?
E.g.:
void Func(const int val) {
const int minVal = 100;
if(val > minVal) {
// Complex code block
}
}
...
Func(200);
for(int i = 0; i < 1000; ++i)
Func(50);
How can I check that Func(50), and the entire for loop, is optimized away?
In this case, the compiler should have all the elements to take such a decision.
This cannot be answered in a generalized manner. It will depend on a variety of factors. Results vary between compilers, and whether or not the code will be optimized out will depend on the level of optimization.
An unoptimized build (ie. O0) will more than likely keep the check, as those will usually not even inline anything to make debugging easier (thus, it can never know what value "val" has.
Optimized builds can and optimize this situation, with one catch: The compiler needs to actually be able to see the functions definition (not declaration) in the translation-unit. If you declare "func" in a header, define it's implementation in a cpp-file, and use "func" in another cpp-file, it won't be able to optimize it, unless some kind of link-time code generation is used. Furthermore, the compilers evaluation must determine that "func" is actually something worth inlining. This will be likely for a small function, but for larger ones, it becomes less likely. There are hints and instructions for the compiler to inline certain functions, but those should almost never be used.
But since we are in C++, let's answer one more question: What if you actually need to ensure that the block is optimize away, maybe even in debug-builds? Well, we can do this, though it has downsides:
Using non-type template parameters, you can actually specify a compile-time constant parameter to the function. Changing "minVal" to an actual constexpr constant, we can use "if constexpr" to force the compiler to do this check at compile-time (at least if you have access to c++17). Now I'm not saying you should do this - it has obvious downsides. Now "Val" must actually be a constant parameter, for once. Also, it will force multiple instantiations of the same function, for every "Val" that is passed in, in every compilation-unit. It can have a negative impact on compile-time. But it's an option, if your use-case for whatever reason requires it. Though in practise, if constexpr is something that you mostly use in meta-programming contexts where you are already inside a template-function.