Точка последовательности после оператора возврата?

В своем ответе на вопрос я объяснил, что произошло, когда postfix ++ использовался для глобальной переменной в той же строке, что и return заявление.

В информативном приложении C к C11 говорится, что сразу после return и ссылается на нормативную главу 6.8.6.4, где текст, касающийся точек последовательности, не может быть найден.

Где в стандарте C можно найти нормативный текст о том, что после return заявление?

(Я нашел только нормативный текст с указанием этого для библиотечных функций, как особый случай, в 7.1.4/3.)

2 ответа

Решение

C 2011 (черновик n1570) 6.8 4: "Каждое из следующего является полным выражением: … (необязательное) выражение в выражении возврата. Существует последовательность последовательности между оценкой полного выражения и оценкой следующего полного выражения, которое будет оценено ".

Таким образом, технически точка последовательности находится не после возврата, а между оценкой выражения в возвращении и следующим выражением. Рассмотрим этот код, который вызывается, когда a изначально 0:

int a = 0;

int Foo(void) { return a++; }

void Bar(void)
{
    int b = Foo() + a;
    …
}

В Foo() + a, будь то Foo() или же a оценивается первым не определено. Мы рассмотрим оба порядка в свете обоих потенциальных правил (точка последовательности после возврата и точка последовательности между выражением возврата и следующим полным выражением). Если реализация делает a Во-первых, тогда это должно сделать:

a
Sequence point
Foo()
+

и затем последует какое-то другое полное выражение, так что по любому правилу будет точка последовательности, и этот код в любом случае одинаков, насколько нам известно. Результатом является то, что b установлен на 0.

Если реализация делает Foo() сначала, затем, с правилом "указатель последовательности после возврата", реализация должна выполнить:

Sequence point
Foo()
Sequence point
a
+

Этот код определил бы поведение: a увеличивается на побочный эффект в Fooи это завершено до a доступ, то + выполняется. Результатом является то, что a установлено в 1. Хотя результат может быть 0 или 1 с этим правилом "точка последовательности после возврата", просто не определено, какой из этих двух порядков используется; поведение не является полностью неопределенным.

Однако, если реализация делает Foo() сначала и использует стандартное правило C "точка последовательности между выражением возврата и следующим полным выражением", затем мы имеем:

Sequence point
Foo()
???
a
???
+
???

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

Следовательно, правило "точка последовательности после выражения возврата и до следующего полного выражения" отличается от "точки последовательности сразу после возврата"; первый имеет неопределенное поведение в этом примере, а второй нет.

Я не думаю, что вы найдете то, что ищете. no text regarding sequence points can be found это правда, это подразумевается только в разделе 6.8 p4.

Стандарт C++ (ISO/IEC 14882:2003) в разделе 1.9 (сноска 11) устанавливает тот факт, что точка последовательности после возврата явно не написана нигде в стандартах C:

11) Точка последовательности при возврате функции явно не указана в ISO C и может считаться избыточной с точками последовательности в полных выражениях, но дополнительная ясность важна в C + +. В C++ существует больше способов, которыми вызываемая функция может прекратить свое выполнение, например, выброс исключения.

Другие вопросы по тегам