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.