Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function with template bool argument: guaranteed to be optimized?

Tags:

c++

templates

In the following example of templated function, is the central if inside the for loop guaranteed to be optimized out, leaving the used instructions only?

If this is not guaranteed to be optimized (in GCC 4, MSVC 2013 and llvm 8.0), what are the alternatives, using C++11 at most?

NOTE that this function does nothing usable, and I know that this specific function can be optimized in several ways and so on. But all I want to focus is on how the bool template argument works in generating code.

template <bool IsMin>
float IterateOverArray(float* vals, int arraySize) {

    float ret = (IsMin ? std::numeric_limits<float>::max() : -std::numeric_limits<float>::max());

    for (int x = 0; x < arraySize; x++) {
        // Is this code optimized by the compiler to skip the unnecessary if?
        if (isMin) {
            if (ret > vals[x]) ret = vals[x];
        } else {
            if (ret < vals[x]) ret = vals[x];
        }
    }

    return val;

}
like image 937
manatttta Avatar asked Oct 16 '25 13:10

manatttta


1 Answers

In theory no. The C++ standard permits compilers to be not just dumb, but downright hostile. It could inject code doing useless stuff for no reason, so long as the abstract machine behaviour remains the same.1

In practice, yes. Dead code elimination and constant branch detection are easy, and every single compiler I have ever checked eliminates that if branch.

Note that both branches are compiled before one is eliminated, so they both must be fully valid code. The output assembly behaves "as if" both branches exist, but the branch instruction (and unreachable code) is not an observable feature of the abstract machine behaviour.

Naturally if you do not optimize, the branch and dead code may be left in, so you can move the instruction pointer into the "dead code" with your debugger.


1 As an example, nothing prevents a compiler from implementing a+b as a loop calling inc in assembly, or a*b as a loop adding a repeatedly. This is a hostile act by the compiler on almost all platforms, but not banned by the standard.

like image 91
Yakk - Adam Nevraumont Avatar answered Oct 18 '25 03:10

Yakk - Adam Nevraumont



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!