Поведение оператора после инкремента относительно оператора запятой? - PullRequest
4 голосов
/ 03 апреля 2020

В следующем коде:

int main() {
   int i, j;

   j = 10;
   i = (j++, j+100, 999+j);

   cout << i;

   return 0;
}

Выходное значение равно 1010 .

Однако это не должно быть 1009, поскольку ++ должно быть сделано после используется целое выражение?

Ответы [ 3 ]

8 голосов
/ 03 апреля 2020

Оператор запятой представляет собой точку последовательности: как сказано в стандарте C ++ 17, например:

Каждое вычисление значения и побочный эффект, связанный с левым выражением, секвенируются перед каждым вычислением значения и побочный эффект, связанный с правильным выражением.

Таким образом, действие оператора ++ гарантированно произойдет до того, как 999+j будет оценено.

4 голосов
/ 03 апреля 2020

++ должно быть сделано после использования всего выражения?

Нет. Оператор постфикса оценивает значение старого j и имеет побочный эффект увеличения j.

Оператор запятой вычисляет второй операнд после , первый операнд вычисляется и его оцениваются побочные эффекты.

Пара выражений, разделенных запятой, оценивается слева направо; левое выражение является выражением отброшенного значения (раздел 5) 83 . Каждое вычисление значения и побочный эффект, связанный с левым выражением, упорядочивается перед каждым вычислением значения и побочным эффектом, связанным с правым выражением.

{ ссылка }

3 голосов
/ 03 апреля 2020

Ассоциативность оператора запятой слева направо.

Таким образом, начиная с j++, это будет оцениваться первым (j становится 11)

Затем j + 100 оценивается (без использования)

Затем оценивается 999 + j, что равно 1010

Это самое правое значение присваивается i

Таким образом, выход is 1010

Длинный ответ:

Встроенный оператор запятой

Оператор запятой выражения имеют форма

E1 , E2   

В выражении запятой E1, E2 выражение E1 вычисляется, его результат отбрасывается (хотя, если он имеет тип класса, он не будет уничтожен до конца содержащего полного выражение), и его побочные эффекты завершаются до начала вычисления выражения E2 (обратите внимание, что пользовательский оператор не может гарантировать последовательность) (до C ++ 17).

Это уже отвечает вашему вопрос, но я пройдусь по нему со ссылкой на ваш код:

Start wi что-то простое, например

int value = (1 + 2, 2 + 3, 4 + 5); // value is assigned 9

Поскольку ... выражение E1 вычисляется, его результат отбрасывается ... Здесь, поскольку у нас более 2 Операнды, ассоциативность оператора запятой также вступает в игру.

Однако не должно ли это быть 1009, как "++" должно быть сделано после использования всего выражения?

Теперь см .:

int j = 0;
int i = (j++, 9 + j);

Здесь значение i равно 10, потому что ... и его побочные эффекты завершаются до того, как начинается оценка выражения E2 ... Следовательно, увеличение j оказывает влияние до оценки 9 + j.

Я думаю, теперь вы можете ясно понять, почему ваш

j = 10;
i = (j++, j+100, 999+j);

i присваивается значение 1010 .

...