В чем разница между оператором запятой и разделителем запятой?

  • В C++ маркер запятой (т. е. ,) интерпретируется либо как оператор-запятая, либо как разделитель-запятая.

  • Однако при поиске в сети я понял, что не совсем понятно, в каких случаях токен , интерпретируется как оператор двоичной запятой, а где — как разделитель между операторами.

  • Более того, учитывая несколько утверждений/выражений в одной строке, разделенных , (например, a = 1, b = 2, c = 3;), возникает неясность в порядке их оценки.

Вопросы:

  1. В каких случаях запятая , интерпретируется как оператор, а в каких как разделитель?
  2. Когда у нас есть несколько операторов/выражений в одной строке, разделенных запятой, каков порядок оценки как для случая оператора запятой, так и для случая разделителя запятой?

person 101010    schedule 15.06.2014    source источник
comment
@hackks дубликат, который вы пометили, явно относится к вызовам функций. Таким образом, этот вопрос не является дубликатом того, который вы отметили.   -  person 101010    schedule 16.06.2014
comment
Вы имеете в виду «неясность», когда говорите «мутность»?   -  person pmr    schedule 16.06.2014
comment
@40два; Прочитайте принятый ответ.   -  person haccks    schedule 16.06.2014
comment
@pmr да, я имею в виду, что порядок оценки в любом случае неясен.   -  person 101010    schedule 16.06.2014
comment
Что касается второй части вашего вопроса: порядок оценки оператора запятой слева направо. Порядок разделителя запятой не указан.   -  person haccks    schedule 16.06.2014
comment
Название вопроса кажется фиктивным. Текст вопроса указывает, что вы знаете, в чем разница в поведении оператора запятой и разделителя запятой; но вы задаете синтаксический вопрос о том, в каких случаях символ запятой указывает на оператор запятой.   -  person M.M    schedule 16.06.2014
comment
Ваш вопрос неясен, когда вы спрашиваете о нескольких утверждениях в одной строке. В показанном примере вы говорите об инициализации или присваивании? Поведение очень отличается в этих двух случаях.   -  person Praetorian    schedule 16.06.2014
comment
@Praetorian Прошу прощения за отсутствие выразительности, в связи с тем, что я не носитель языка, я имею в виду оба случая. Я был бы очень признателен за ответ с примерами, подобными тому, который вы опубликовали. Где будущий читатель мог видеть, в каком примере запятая выступает как оператор, а в каком как разделитель. Также обоснование порядка слева направо оператора запятой и то же самое для разделителя.   -  person 101010    schedule 16.06.2014


Ответы (2)


Вы не можете использовать запятую для разделения операторов. , в a = 1, b = 2; — это оператор запятой, аргументами которого являются два выражения присваивания. Порядок оценки аргументов оператора запятой слева направо, поэтому ясно, каков порядок оценки в этом случае.

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

Это ясно выражено в грамматике стандарта C++. Соответствующие производства expression, которые могут быть:

assignment-expression

or

expression , assignment-expression

и expression-list, который совпадает с initializer-list, который представляет собой ,-разделенный список initializer-clause, где initializer-clause:

assignment-expression

or

braced-init-list

, во второй постановке expression является оператором-запятой.

person rici    schedule 15.06.2014

Когда разделитель уместен — в аргументах вызова функции или макроса, или при разделении значений в списке инициализаторов (спасибо за напоминание, @hackcks) — запятая будет использоваться в качестве разделителя. В других выражениях он принимается как оператор. Например,

my_function(a,b,c,d);

это вызов, передающий функции четыре аргумента, тогда как

result=(a,b,c,d);

будет пониматься как оператор запятой. Через ugly можно смешать их, написав что-то вроде

my_function(a,(b,c),d);

Оператор запятой обычно оценивается слева направо.

Первоначальное использование этой операции в C состояло в том, чтобы позволить макросу выполнять несколько операций, прежде чем возвращать значение. Поскольку реализация макроса выглядит как вызов функции, пользователи обычно ожидают, что его можно будет использовать везде, где может быть вызов функции; если макрос расширится до нескольких операторов, это победит. Таким образом, C ввел оператор ,, позволяющий объединить несколько выражений в одно выражение, отбрасывая результаты всех, кроме последнего.

Как указал @hackks, точные правила того, как компилятор определяет, какое значение , было предназначено, исходят из языковой грамматики и ранее обсуждались на Как компилятор узнает, что запятая в вызове функции не является оператор запятой?

person keshlam    schedule 15.06.2014
comment
, также рассматривается как разделитель в списке инициализаторов. - person haccks; 16.06.2014