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
  • 25,191
  • 47
  • 61
  • 93
op414
  • 562
  • 6
  • 14

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
  • 25,191
  • 47
  • 61
  • 93
Renat
  • 6,490
  • 2
  • 19
  • 30
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
  • 190,553
  • 13
  • 166
  • 271