Disturbing order of evaluation
Asked Answered
W

1

7

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?
Wyckoff answered 6/9, 2018 at 11:36 Comment(3)
C++17 changed some cases from UB to unspecified behavior. I guess that's something ¯_(ツ)_/¯Knickerbocker
Bjarne has commented on this before and basically said you shouldn't have to rely on argument evaluation order (which I'm not sure I totally agree with, but he's the boss!). I think historically it stems back to differences in calling conventions of different architecture types (left-to-right vs right-to-left, etc)Pretended
@CoryKramer - the problem with defining a particular order in which arguments are evaluated is that programmers may still find another order more "natural". There are already languages which evaluate left to right and others that evaluate right to left, for example - and which is better is completely subjective, in some cases a religious debate. Coding in a way that is independent of order of evaluation of arguments (in this example, by ensuring that evaluation of the arguments don't do separate modifications of some variable or member of a structure) eliminates all such concerns.Cherry
O
8

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.

Organotherapy answered 6/9, 2018 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.