Является ли точка с запятой действительно точкой последовательности в C?

Согласно этому ответу, в стандарте описаны следующие точки последовательности:

  1. Между оценками указателя функции и фактическими аргументами в вызове функции и фактическим вызовом;

  2. Между вычислениями первого и второго операндов операторов &&, || и ,;

  3. Между оценками первого операнда условного оператора ?: и независимо от того, какой из второго и третьего операндов оценивается;

  4. Конец полного декларатора;

  5. Между вычислением полного выражения и следующим вычисляемым полным выражением. Ниже приведены полные выражения:

    • an initializer;
    • выражение в операторе выражения;
    • управляющее выражение оператора выбора (if или switch);
    • управляющее выражение оператора while или do;
    • каждое из выражений оператора for;
    • выражение в операторе возврата.
  6. Непосредственно перед возвратом из библиотечной функции;

  7. После действий, связанных с каждым спецификатором преобразования функции форматированного ввода/вывода;

  8. Непосредственно перед и сразу после каждого вызова функции сравнения, а также между любым вызовом функции сравнения и любым перемещением объектов, переданных в качестве аргументов этого вызова.

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

Итак, является ли точка с запятой в break; или continue; точкой последовательности?


person Kushagr Jaiswal    schedule 01.06.2021    source источник
comment
Точка с запятой - это точка следования, это упрощение/первое приближение, которое не отражает всех нюансов. Стандартный ОТОН — окончательный источник мудрости. Я не уверен, что это подразумевает. Либо подразумевает, либо нет.   -  person n. 1.8e9-where's-my-share m.    schedule 01.06.2021
comment
@n.'местоимения'.м. Это как раз и есть источник моего замешательства. Куда бы я ни посмотрел, везде прямо упоминается, что точка с запятой — это точка следования. Даже в книге, по которой я изучаю (C Primer Plus, 6e), четко сказано, что точка с запятой — это точка последовательности.   -  person Kushagr Jaiswal    schedule 01.06.2021
comment
Большинство точек с запятой являются разделителями операторов, поэтому вы можете разбить возможные варианты на (1) точки последовательности операторов? и (2) являются ли другие возможные вхождения точки с запятой точками последовательности? Давайте сосредоточимся на (2) и возьмем точку с запятой внутри символа ';'. Не точка последовательности. Конец дискуссии ;)   -  person grek40    schedule 01.06.2021
comment
Есть ли код, который был бы UB в зависимости от того, является ли точка с запятой точкой последовательности? (Со всеми точками последовательности, перечисленными в стандартных оставшихся точках последовательности). Я так не думаю!   -  person Paul Hankin    schedule 01.06.2021
comment
Точка с запятой — это точка следования — это чрезмерное упрощение, справедливое в большинстве случаев. Вы не найдете в стандарте ничего, прямо указывающего, что точка с запятой является точкой последовательности. Однако в синтаксисе есть точка с запятой после большинства вещей, упомянутых в этом Приложении C.   -  person Lundin    schedule 01.06.2021
comment
@Lundin Тогда разве это не должно упоминаться всякий раз, когда кто-то говорит о том, что точка с запятой является точкой последовательности? Следует сказать, что в большинстве случаев точкой с запятой является точка следования.   -  person Kushagr Jaiswal    schedule 01.06.2021


Ответы (2)


Является ли точка с запятой действительно точкой последовательности в C?

Нет. Конкретные семантические языковые конструкции должны иметь точку последовательности после их оценки. (например, например, логический оператор И ...if the second operand is evaluated, there is a sequence point between... - это конкретный). Точка последовательности действительно связана, например, с семантикой (оценка этого происходит до этого), а не с токенами (все происходит до символа ;).

Итак, точка с запятой в разрыве; или продолжить; точка последовательности?

Нет это не так. Вместе с goto они выглядят как исключение из разговорного правила.

Это не вызов функции, не логический оператор && ||, не оператор ,, не тернарный оператор ?:, не объявление, не полное выражение - его нет в приведенном вами списке (список взят из ПРИЛОЖЕНИЕ C), он никоим образом не изменчив и не выполняет ввод-вывод. Итак, под когда вы устранили невозможное, то, что осталось, однако маловероятно, должно быть правдой логика действительно не имеет точки следования после break; или continue;.

person KamilCuk    schedule 01.06.2021
comment
Хотя точка с запятой не является точкой следования, мы можем спросить, является ли семантика, указанная в стандарте C, такой же, если мы добавим правило «В каждой точке с запятой есть точка следования». Ответ - нет: из-за дефекта в стандарте не существует точка следования после оператора return, а поведение int foo(int *p) { return ++*p; } int main(void) { int a = 0; a = foo(&a); } не определено стандартом (из-за C 2018 6.5 2), но было бы, если бы точкой следования была точка с запятой. - person Eric Postpischil; 01.06.2021
comment
Однако, помимо этого дефекта, изменится ли семантика C, если правило будет добавлено? - person Eric Postpischil; 01.06.2021

То есть точка с запятой в break; или continue; является точкой следования?

Лучше спросите себя, почему это не должно быть точкой следования?

break и continue просто замаскированы под goto или jmp.

goto всегда нужна метка, она же указатель, она же аргумент, чтобы иметь возможность прыгать, то же самое касается break и continue (они получают свою метку, неявную из окружающего цикла).

...

Да, точка с запятой в break; или continue; — это точка следования.

person paladin    schedule 01.06.2021
comment
Yes, the semicolon in break; or continue; is a sequence point. Почему? why shouldn't it not be a sequence point? Я спросил, и теперь я знаю ответ. goto always needs a label, Требуется ли свойство метки, связанное с точкой следования? Почему? - person KamilCuk; 01.06.2021
comment
@KamilCuk goto x; — это полное выражение, как и return x;, так же как и break; и continue; полное выражение. ; между двумя полными выражениями является точкой последовательности. - person paladin; 01.06.2021
comment
is a full expression Это полное выражение? Я не вижу его в списке. return указан, goto нет. - person KamilCuk; 01.06.2021
comment
Этот список неполный, это просто список примеров. Уместно только -> Между оценкой полного выражения и следующим полным выражением, которое нужно оценить. -› так что ищите определение полного выражения. - person paladin; 01.06.2021
comment
Как правило, отвечая на вопросы типа языкового юриста, никогда не спрашивайте себя и всегда спрашивайте стандартную спецификацию или аналогичный источник. - person grek40; 01.06.2021
comment
@grek40 Извините, но goto x; явно полное выражение. Попробуйте опровергнуть меня. - person paladin; 01.06.2021
comment
@paladin на самом деле, мой комментарий не зависит от того, прав ты или нет. Он нацелен на вашу структуру рассуждений, а не на результирующее утверждение. Вы не можете отрицать, что ваш ответ начинается с Лучше спросите себя. Я отмечаю, что этот подход не подходит для такого рода вопросов. - person grek40; 01.06.2021
comment
Метка, используемая goto, подпадает под категорию синтаксиса, называемую маркированным-оператором, которая должна использоваться вместе с другим оператором, чтобы иметь смысл, синтаксис identifier : statement. Оператор Where может, например, быть пустым выражением оператора ;. Этот синтаксис меток не имеет ничего общего с break или continue, поскольку в их синтаксисе нет идентификаторов меток. - person Lundin; 01.06.2021
comment
@paladin: goto x; не является полным выражением, как определено в C 2018 6.8 4, потому что это вообще не выражение. Выражения определены в C 2018 6.5, и грамматика для них не включает операторы goto. - person Eric Postpischil; 01.06.2021
comment
@EricPostpischil Полное выражение — это выражение, которое не является частью другого выражения или декларатора. -› Выражение — это последовательность операторов< /b> и операнды, определяющие вычисление значения, или обозначающие объект или функцию, или создающие побочные эффекты, или выполняющие их комбинацию. -> указатель на переменную (операнд) является оператором -> void* label_pointer; MYLABEL: label_pointer = &MYLABEL; goto *label_pointer; -> goto x; является полным выражением - person paladin; 01.06.2021
comment
@paladin: Во-первых, метки как значения являются расширением GCC и поэтому не имеют отношения к тому, что определяет стандарт C. Во-вторых, goto *label_pointer; не goto x;. Даже если GCC определяет свое расширение для включения выражения в свой расширенный оператор goto, это не означает, что в стандартном операторе goto есть выражение. Если на то пошло, даже если бы GCC определил стандартную инструкцию goto как содержащую выражение или как выражение, это не изменило бы того, что говорит стандарт C. Стандарт C определяет выражения с формальной грамматикой в ​​6.5, а goto в нем нет. - person Eric Postpischil; 01.06.2021
comment
goto x; — это полное выражение, как и return x; Но return x; — не полное выражение. x в return x; есть. - person Language Lawyer; 01.06.2021