Home > Enterprise >  Why the object is not getting modified when passing the callable object with reference to async
Why the object is not getting modified when passing the callable object with reference to async

Time:07-15

Since we are passing the object by reference to std::async, it will call the operator () on same object, then why its member variable is not getting updated

struct Y
{
    int m_val;
    Y():m_val(0){}
    double operator()(double val)
    {
        m_val = val*val;
        return m_val;
    }
};
int main()
{
    Y y;
    auto f=std::async(std::ref(y),2);
    cout <<"Returned value " << f.get() << ", Modified value " << y.m_val << endl;
    return 0;
}

output-

Returned value 4, Modified value 0

As per my understanding it should have called y(2) so y.m_val should be updated to 4, however it is printed as 0 in output. Please clarify what am I missing.

CodePudding user response:

Before C 17, the evaluation of arguments to << was unsequenced. That means you have no guarantee that f.get() would be called before y.m_val's value is taken.

As a consequence, your program has a potential data race, and therefore undefined behavior.

Since C 17, the evaluation order is specified as left-to-right, and so the result you expect is guaranteed.


For C 11/14 you can fix this by separating the output statement into multiple statements:

std::cout << "Returned value " << f.get();
std::cout << ", Modified value " << y.m_val << endl;

or even by calling f.get() in a separate statement before the output (storing the result to a variable), which is generally a good idea anyway if your call has side effects.

  • Related