10

I am in the process of refactoring some code using C++ atomics. The code looks like this:

std::atomic<bool> someFlag{}; // This can be set to true using a public method

// ...

const bool cond1 { someFunction() };
const bool cond2 { otherFunction() };

if (someFlag.load())
{
    someFlage.store(false);

    if (cond1 && cond2)
    {
        performSomeAction();
    }
}

I'm currently planning to rewrite the if statement like this:

if (std::atomic_exchange(&someFlag, false) &&
    cond1 && cond2)
{
    performSomeAction();
}

What is extremely important, is that after this if statement, the someFlag variable is set to false. I therefore want to make sure that the call to atomic_exchange always occurs, regardless of the value of cond1 and cond2. Can I be guaranteed that this will be the case since boolean expressions are evaluated left to right, regardless of optimisation settings?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
op414
  • 582
  • 5
  • 15

2 Answers2

16

Yes, the order is guaranteed. From cppreference.com:

Every value computation and side effect of the first (left) argument of the built-in logical AND operator && and the built-in logical OR operator || is sequenced before every value computation and side effect of the second (right) argument.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Renat
  • 7,718
  • 2
  • 20
  • 34
7

In if (std::atomic_exchange(&someFlag, false) && cond1 && cond2)

  • std::atomic_exchange(&someFlag, false) will be called first.

  • If evaluate to true, evaluates cond1

  • If cond1 is true, evaluates cond2.

  • and finally performSomeAction() if cond2 is also true.

Jarod42
  • 203,559
  • 14
  • 181
  • 302