2

So here is the code (the program calculates the area of ring with specified outter and inner radiuses, nothing too special):

#include <iostream>

bool f(double ro, double ri, double &s) 
{
    const double eps = 1e-12;
    if (ro > ri + eps) 
    {
        const double pi = acos(-1);
        //s = pi * (ro * ro) - pi * (ri * ri);
        s = pi * (ro + ri) * (ro - ri);
        return true;
    }
    return false;
}

int main()
{
    double s = 0;
    double ro, ri;  
    std::cin >> ro >> ri;
    std::cout << f(ro, ri, s) << ' ' << s << '\n'; 
    std::cout << s;
}

The question is, why, for example, for input 5 4 the output will be

1 0
28.2743

, not

1 28.2743
28.2743

?

LogXx
  • 23
  • 4
  • 2
    Order of evaluation of arguments is not fixed in C++. Compiler is free to evaluate `s` first and call `f` later. – yeputons Nov 16 '20 at 11:45
  • 2
    Before C++17 it's even worse as interleaving is allowed between computations of different arguments. Starting with C++17, there are some guarantees, though: e.g. in `a = b;` the left side will be evaluated after the right side. – yeputons Nov 16 '20 at 11:46
  • 2
    Actually, there are guarantees regarding `< – yeputons Nov 16 '20 at 11:47
  • @yeputons yep, with c++17 enabled, it works as expected, many thanks! x) – LogXx Nov 16 '20 at 11:49

1 Answers1

3

Order of evaluation rules have evolved, in particular, in C++17 for E1 << E2.

std::cout << f(ro, ri, s) << ' ' << s << '\n';

is guaranteed to be evaluated in expected order (left to right for E1 << E2 ) in C++17 whereas it was unspecified before.

Jarod42
  • 173,454
  • 13
  • 146
  • 250