Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function parameters evaluation order: is it UB if we pass reference?

This is undefined behavior:

void feedMeValue(int x, int a) {
  cout << x << " " << a << endl;
}
int main() {
  int a = 2;
  int &ra = a;
  feedMeValue(ra = 3, a); // equivalent to: feedMeValue(a = 3, a) (see note bellow)
  return 0;
}

because depending on what parameter gets evaluated first we could call (3, 2) or (3, 3).

However this:

void feedMeReference(int x, int const &ref) {
  cout << x << " " << ref << endl;
}

int main() {
  int a = 2;
  int &ra = a;
  feedMeReference(ra = 3, a); // equivalent to: feedMeReference(a = 3, a) (see note bellow)
  return 0;
}

will always output 3 3 since the second parameter is a reference and all parameters have been evaluated before the function call, so even if the second parameter is evaluated before of after ra = 3, the function received a reference to a which will have a value of 2 or 3 at the time of the evaluation, but will always have the value 3 at the time of the function call.

Is the second example UB? It is important to know because the compiler is free to do anything if it detects undefined behavior, even if I know it would always yield the same results.


Note: I will leave feedMeReference(ra = 3, a) as some answers reference ra but you should note that a simpler equivalent problem to this is if we call feedMeReference(a = 3, a) (simpler because we eliminate ra which is just in the way of our issue (the second parameter being a reference)).

like image 477
bolov Avatar asked Jun 12 '14 08:06

bolov


Video Answer


1 Answers

That's an interesting question. In your first case, there is undefined behavior because an object is modified and also accessed without an intervening sequence point (in the language of C++03---C++11 used different language to say essentially the same thing). In the second, there is no undefined behavior, because initializing a reference with an lvalue doesn't access the object, so the only access is ra = 3. (Calling the function establishes a sequence point, so accesses in the function have a sequence point between them and the ra = 3.)

like image 191
James Kanze Avatar answered Oct 30 '22 08:10

James Kanze