4

I am trying to learn how expression are evaluated in C++. So trying out and reading different examples. Below is the code about which i am unable to understand whether it will produce undefined behavior or not. The code is from here. So i guess since they have used it, this must not be UB. But i have my doubts.

#include <iostream>
int main()
{
    int n = 1;
    //std::cout << n << " " << ++n << std::endl;//this is undefined behavior i am sure
    int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);//will this also produce UB because here also we have cout in the same manner as above?
    std::cout << "m = " << (++m, m) << '\n';
}

As you can see in the above code, i am sure that the statement:

cout << n << " " << ++n << endl;

produces undefined behavior. My questions are:

  1. But will the same statement used inside the comma operator produce UB(as shown in the code above)? That is, will the below given statement produce UB.
int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);
  1. How can we explain what is going on in terms of sequence-before, unsequenced etc the behavior of the above mentioned statement.

PS: I know since C++11 we use sequence-before etc. instead of sequence point so that why i asked the explanation in terms of current standard.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • None of this is UB in C++17 and up. – n. m. could be an AI Sep 24 '21 at 10:01
  • with your edit you are now asking 3 questions in total. Note that my answer adresses 1 and 2 but not the one in your PS. Please only one question per question and please try to not change the question to ask for something else after you received answers. – 463035818_is_not_an_ai Sep 24 '21 at 10:06
  • you arent using `std::cout << n << " " << ++n;` "inside the comma operator". – 463035818_is_not_an_ai Sep 24 '21 at 10:06
  • I added only one statement to my question because i thought it will clarify what i am asking. I just noticed now that there is a comma after `'\n'` inside the command operator which i missed originally. Everything makes sense now that i have seen that comma i missed spotting. – Jason Sep 24 '21 at 10:11

1 Answers1

7

From the same page on cppreference:

In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded (although if it has class type, it won't be destroyed until the end of the containing full expression), and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing) (until C++17).

As the comma-operator in your code is the built-in one, the sequencing between ++n, std::cout << "n = " << n << '\n' and the other expressions is well defined. There is no undefined behavior.

And because you might have read already the above, here is the wording from the standard:

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded-value expression. The left expression is sequenced before the right expression ([intro.execution]).

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185