Home > Blockchain >  Undefined Behavior when using Comma Operator in C
Undefined Behavior when using Comma Operator in C

Time:09-24

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. I want to know when we use std::cout << n << " " << n; outside comma operator it is UB but when we use it inside the comma operator how will it become defined behavior.

CodePudding user response:

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]).

  • Related