Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a standards conforming C++ compiler allowed to optimize away branching on <= 0 for unsigned integers?

Tags:

c++

Consider this code:

void foo(size_t value)
{
    if (value > 0) { ... }    // A

    if (value <= 0) { ... }   // B
}

Since an unsigned cannot be negative, could a standards conforming C++ compiler optimize away the B statement? Or would it just choose to compare to 0?

like image 320
Johann Gerell Avatar asked Dec 07 '25 02:12

Johann Gerell


2 Answers

Well, it clearly cannot optimise away the B statement altogether—the condition body does execute when value is 0.

Since value cannot, by any means, be < 0, the compiler can of course transform B into if (value == 0) { ... }. Furthermore, if it can prove (remember that the standard mandates strict aliasing rules!) that value is not changed by statement A, it can legally transform the entire function like this:

void foo(size_t value)
{
    if (value > 0) { ... }    // A
    else { ... }   // B
}

Or, if it happens to know that the target architecture likes == better, into this:

void foo(size_t value)
{
    if (value == 0) { ... }    // B
    else { ... }   // A
}
like image 169
Angew is no longer proud of SO Avatar answered Dec 10 '25 08:12

Angew is no longer proud of SO


If the code is correctly written, B cannot be optimized away, because value can be zero, though the particular comparison used can be replaced with an equivalent one as shown in Angew's answer. But if the statements in B invoke undefined behavior, all bets are off. For ease of reference, let's rewrite foo as

void foo(size_t value)
{
    if (value > 0) bar(); // A
    if (value <= 0) baz(); // B
}

If the compiler can determine that baz() invokes undefined behavior, then it can treat it as unreachable. From that, it can then deduce that value > 0, and optimize foo into

void foo(size_t value)
{
    bar();
}
like image 32
T.C. Avatar answered Dec 10 '25 09:12

T.C.