Точка последовательности после оператора возврата?
В своем ответе на вопрос я объяснил, что произошло, когда 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++ существует больше способов, которыми вызываемая функция может прекратить свое выполнение, например, выброс исключения.