Как читать и понимать стандарты C & С++ и грамматику языка, используемую в нем?
Я часто нахожу стандарты C и С++ трудными для чтения и понимания, даже простые английские предложения и их формулировки дают ужасный опыт. Наверху, грамматика языка полностью ад. Я уверен, что у многих одинаковое чувство, по крайней мере, мои друзья.
Я хотел бы это понять на некоторых примерах. Начнем с этого (который пытается объяснить, почему the conditional expression in C++
отличается от the conditional expression in C
: (цитируется из wikipedia)
Связывание операторов в C и С++ (в соответствующем Стандарты) на факторизованном языке грамматики, а не приоритета Таблица. Это создает некоторые тонкие конфликты. Например, в C, синтаксис условного выражения является:
логическое-OR-выражение? выражение: условное выражение
а в С++ -
логическое-OR-выражение? выражение: Назначение выражение
Следовательно, выражение:
e = a < d? a ++: a = d
анализируется по-разному в двух языки. В C это выражение является синтаксическая ошибка, но многие компиляторы разбора это как:
e = ((a < d? a ++: a) = d)
что является семантической ошибкой, поскольку результат условного выражения (который может быть ++) не является значением lvalue. В С++ он анализируется как:
e = (a < d? a ++: (a = d))
который является допустимым выражением.
Пожалуйста, объясните жирный текст в приведенной выше цитате! Пожалуйста, объясните грамматику несколькими примерами (особенно теми, где C и С++ отличаются).
EDIT: Я просто хочу знать , как читать и понимать их. Я имею в виду, если бы я объяснил это на разговорном английском, то как бы я это сделал?
Ответы
Ответ 1
Вот описание грамматики С++ для выражений, которая определяет выражение-присваивание как
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
На простом английском языке выражение-присваивание может быть либо условным выражением, либо унитарным выражением, за которым следует оператор-присваивание, за которым следует выражение-присваивание. Итак, ваш следующий вопрос: "какое условное выражение", и вы проконсультируетесь с этой частью грамматики и продолжаете идти, пока не достигнете дна!
Итак, на С++ вы можете видеть, что оператор, на который вы ссылаетесь, может принимать "условное выражение", как в C, но также присваивание
Итак, при включении вашей "C" вы смотрите на конечную часть a = d
оператора в качестве назначения, которое синтаксис C не должен разрешать. Вместо этого казалось бы, что некоторые компиляторы просто анализируют конечную часть оператора как a
, чтобы дать
e = (a < d ? a++ : a) = d
Но в С++ это действительно так, чтобы найти там назначение, поэтому a = d
полностью принимается как окончательное выражение, поэтому вы получаете
e = (a < d ? a++ : (a = d))
Ответ 2
Вы должны указать, что такое выражение-присваивание. Он определен в стандарте С++ 03 в 5.17/1 [expr.ass]:
assignment-expression:
conditional-expression
logical-or-expression assignment-operator assignment-expression
throw-expression
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ˆ= |=
В нем говорится, что выражение-присваивание может быть:
- Условное выражение
- Логическое или выражение, за которым следует оператор-присваивание, за которым следует выражение-присваивание
- Выражение-выражение.
Я не цитирую грамматическое определение всего, потому что это будет довольно огромным (особенно, потому что выражение условий охватывает много вещей).
Итак, первое, что мы видим, это то, что выражение-присваивание может быть условным выражением, поэтому мы используем синтаксис C. Что добавляет стандарт С++, так это то, что правая сторона :
также может быть чем-то вроде оператора присваивания или броска.
Приведенный пример хорош: e = a < d ? a++ : a = d
.
Здесь правая часть :
является логическим или выражением (a
, потому что унитарное выражение включено в логическое или выражение), за которым следует оператор-присваивание (=
), за которым следует выражение-присваивание (d
, поскольку унарное выражение включено в выражение-присваивание).
Ответ 3
В основном, такие вещи, как:
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
(как упоминалось в некоторых других ответах здесь) являются правилами, используемыми для описания "грамматики" действительного C (или С++). Эти записанные правила придерживаются определенной грамматики, тоже. поэтому я бы посоветовал вам изучить эту грамматику, чтобы вы могли читать и понимать правила.
Для начала вы можете изучить, например. Бэксу-Наур Форма, если вы еще этого не знаете. (Моя ссылка относится к статье в Википедии по этой теме.) Хотя стандарт С++ не использует форму Backus-Naur (IIRC), он достаточно похож на вас, чтобы вы начали.