Как читать и понимать стандарты C & C ++ и используемую в них грамматику языка? - PullRequest
15 голосов
/ 04 декабря 2010

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

Я хотел бы понять это на некоторых примерах.Давайте начнем с этого (который пытается объяснить, почему the conditional expression in C++ отличается от the conditional expression in C: (цитируется wikipedia )

привязка операторов в C и C ++ определяется (в соответствующих стандартах) факторизованной грамматикой языка, а не таблицей приоритетов. Это создает некоторые тонкие конфликты. Например, в C синтаксис для условного выражения:

выражение логического ИЛИ? Выражение: условное выражение

в то время как в C ++ это:

выражение логического ИЛИ?выражение: присваивание-выражение

Следовательно, выражение:

e = a

анализируется по-разному в двух языках.В C это выражение является синтаксической ошибкой, но многие компиляторы анализируют его как:

e = ((a

, что является семантической ошибкой,поскольку результат условного выражения (который может быть ++) не является lvalue, в C ++ он анализируется как:

е = (а <д?a ++: (a = d)) </p>

, которое является допустимым выражением.

Пожалуйста, кто-нибудь объяснит жирный текст в приведенной выше цитате!Пожалуйста, объясните грамматику еще несколькими примерами (особенно те, где C и C ++ отличаются).

РЕДАКТИРОВАТЬ: Я просто хочу знать , как читать и понимать их.Я имею в виду, если бы я объяснил это на разговорном английском, то как бы я это сделал?

Ответы [ 3 ]

6 голосов
/ 04 декабря 2010

Вы должны обратиться к выражению присваивания . Это определено в стандарте C ++ 03 в 5.17 / 1 [expr.ass]:

assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator assignment-expression
        throw-expression

assignment-operator: one of
        = *= /= %= += -= >>= <<= &= ˆ= |=

То, что говорится, это то, что выражение присваивания может быть либо :

  • A условное выражение
  • A логическое или-выражение , за которым следует оператор присваивания , за которым следует выражение-присваивание
  • A throw-выражение .

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

Итак, первое, что мы видим, это то, что выражение присваивания может быть условным выражением, поэтому у нас есть синтаксис языка C. Стандарт C ++ добавляет, что правая часть : также может содержать нечто, содержащее оператор присваивания или throw .

Приведенный пример хорош: e = a < d ? a++ : a = d.

Здесь правая часть : представляет собой логическое или-выражение (a, потому что унарное выражение включено в логическое-или -expression ), за которым следует оператор присваивания (=), за которым следует выражение-присваивание (d, поскольку унарное выражение включено в назначение выражение ).

6 голосов
/ 04 декабря 2010

Вот описание грамматики C ++ для выражений , которая определяет выражение присваивания как

assignment-expression:
    conditional-expression 
    unary-expression assignment-operator assignment-expression

В простом английском языке выражение присваивания может быть условным выражением ИЛИунарное выражение, за которым следует оператор присваивания, за которым следует выражение присваивания.Итак, ваш следующий вопрос - «что такое условное выражение», и вы обращаетесь к этой части грамматики и продолжаете, пока не достигнете дна!

Итак, в C ++ вы можете видеть, что оператор, на который вы ссылались, может взять'условное выражение', как в C, но также и присваивание

Итак, с надетой 'C', вы смотрите на конечную a = d часть оператора как присваивание, которое синтаксис C не должен 'я не могуВместо этого может показаться, что некоторые компиляторы разбирают последнюю часть оператора просто как a, чтобы выдать

 e = (a < d ? a++ : a) = d

Но в C ++ допустимо найти там назначение, поэтому a = d принимаетсяв качестве окончательного выражения, так что вы получите

 e = (a < d ? a++ : (a = d))
1 голос
/ 04 декабря 2010

По сути, такие вещи, как:

assignment-expression:
    conditional-expression 
    unary-expression assignment-operator assignment-expression

(как упоминалось в некоторых других ответах здесь) - это правила, используемые для описания «грамматики» действительного C (или C ++).Эти записанные правила также соответствуют определенной грамматике - поэтому я бы посоветовал вам изучить эту грамматику, чтобы вы могли читать и понимать правила.

Для начала,Вы можете изучить, например, форму Бэкуса-Наура , если вы еще этого не знаете.(Моя ссылка ведет к статье Википедии на эту тему.) Хотя стандарт C ++ не использует форму Бэкуса-Наура (IIRC), он достаточно похож, чтобы начать работу.

...