Как читать и понимать стандарты 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), он достаточно похож на вас, чтобы вы начали.