I know some metaprogramming techniques in C++ to compute constants at compile-time. Most of the time branching in metafunctions is done through the ternary operators which can be evaluated at compile-time on the contrary of standard if/else.
But regarding this kind of function:
template <unsigned int N>
void f()
{
if (N == 0) {
// Some computations here
} else if (N <= 42) {
// Some computations here
} else {
// Some computations here
}
}
What will the compiler do (assuming -O3
) ?
The compiler knows that f<0>()
will always branch on the first case, f<32>()
will always branch on the second case, and f<64>()
will always branch on the third case.
Will the compiler remove branches that will always be false
? Will it directly branch to the only valid case ?
The optimizer will remove the branch and the code in the unused branches, but beware: the compiler needs to process the function before the optimizer even gets a chance to look at the code, which means that all branches must be valid (compilable) for all values of N
.
For example, if the second branch contained:
} else if (N <= 42) {
char data[50 - N];
// other code
The compiler will fail to instantiate the template for N >= 50
even though the branch will be removed by the optimizer.