Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disturbing order of evaluation

When I work with my favorite containers, I tend to chain operations. For instance, in the well-known Erase–remove idiom:

v.erase( std::remove_if(v.begin(), v.end(), is_odd), v.end() );

From what I know of the order of evaluation, v.end() (on the rhs) might be evaluated before the call to std::remove_if. This is not a problem here since std::remove* only shuffle the vector without changing its end iterator.

But it could lead to really surprising constructs, like for instance (demo):

#include <iostream>

struct Data
{
    int v;
    int value() const { return v; }
};

auto inc(Data& data)           { return ++data.v; }
void print_rhs(int, int value) { std::cout << value << '\n'; }

int main()
{
    Data data{0};
    print_rhs(inc(data), data.value()); // might print 0
}

This is surprising since print_rhs is called after inc has been called; which means data.v is 1 when print_rhs is called. Nevertheless, since data.value() might be evaluated before, 0 is a possible output.

I think it might be a nice improvement if the order of evaluation would be less surprising; in particular if the arguments of a function with side effects were evaluated before those without.

My questions are then:

  • Has that change ever been discussed or suggested in a C++ committee?
  • Do you see any problem it could bring?
like image 984
YSC Avatar asked Sep 06 '18 11:09

YSC


1 Answers

Has that change ever been discussed or suggested in a C++ committee?

Probably.

Do you see any problem it could bring?

Yes. It could reduce optimization opportunities which exist today, and brings no direct benefit other than the ability to write more one-liners. But one-liners are not a good thing anyway, so this proposal would probably never get past -99 points.

like image 92
John Zwinck Avatar answered Oct 09 '22 17:10

John Zwinck