Я использовал этот пост Неопределенные Точки Поведения и Последовательности документировать неопределенное поведение (UB) в С программа, и мне было указано, что C and C++ have their own divergent rules for this [sequence points]
, Так в чем же различия между С а также C ++ когда дело доходит до точек последовательности и связанных UB? Я не могу использовать пост о C ++ последовательности для анализа того, что происходит в С код?
* Конечно, я не говорю об особенностях C++
не относится к C
,
Этот вопрос состоит из двух частей, и мы можем без особых проблем заняться сравнением правил точек последовательности. Это не дает нам слишком далеко, хотя, C и C ++ разные языки, которые имеют разные стандарты ( последний стандарт C ++ почти в два раза больше, чем последний стандарт C) и даже несмотря на то, что C ++ использует C в качестве нормативной ссылки, было бы неверно цитировать стандарт C ++ для C и наоборот, независимо от того, насколько похожими могут быть определенные разделы. Стандарт C ++ явно ссылается на стандарт C, но это для небольших разделов.
Вторая часть представляет собой сравнение неопределенное поведение между C и C ++ могут быть некоторые большие различия, и перечисление всех различий в неопределенном поведении может быть невозможным, но мы можем привести некоторые показательные примеры.
Очки последовательности
Поскольку мы говорим о последовательность точек тогда это покрывает до C ++ 11 и до C11. Правила точки последовательности, насколько я могу судить, между черновыми стандартами C99 и Pre C ++ 11 не сильно отличаются. Как мы увидим в некоторых из приведенных мною примеров различного неопределенного поведения, правила точки последовательности не играют в них никакой роли.
Правила точек последовательности описаны в Наиболее близкий проект стандарта C ++ к C ++ 03 раздел 1.9
Выполнение программы который говорит:
При оценке каждого из выражений
a && b
a || b
a ? b : c
a , b
используя встроенное значение операторов в этих выражениях (5.14, 5.15, 5.16, 5.18), после
оценка первого выражения14).
Я буду использовать список точек последовательности из черновика стандарта C99 Annex C
Хотя это не является нормативным, я не могу найти несогласия с нормативными разделами, на которые оно ссылается. Это говорит:
Ниже приведены точки последовательности, описанные в 5.1.2.3:
Следующие записи, похоже, не имеют эквивалентов в проекте стандарта C ++, но они взяты из стандартной библиотеки C, которую C ++ включает в качестве ссылки:
Так что здесь нет особой разницы между C и C ++.
Неопределенное поведение
Когда дело доходит до типичных примеров точек последовательности и неопределенного поведения, например, описанных в разделе 5
выражение Имея дело с изменением переменной более одного раза в точках последовательности, я не могу придумать пример, который не определен ни в одном, а в другом. В С99 это говорит:
Между предыдущей и следующей точкой последовательности объект должен иметь
сохраненное значение изменено не более одного раза путем оценки
выражение.72) Кроме того, предыдущее значение должно быть прочитано только
определить значение для хранения.73)
и это обеспечивает эти примеры:
i = ++i + 1;
a[i++] = i;
и в C ++ это говорит:
За исключением случаев, где указано, порядок оценки операндов отдельных
операторы и подвыражения отдельных выражений, а также порядок
в каких побочных эффектах происходит, не определено.57) Между
в предыдущей и следующей последовательности последовательности скалярный объект должен храниться
значение, измененное не более одного раза путем оценки выражения.
Кроме того, предварительное значение должно быть доступно только для определения
значение для хранения. Требования этого пункта должны быть выполнены
для каждого допустимого порядка подвыражений полного
выражение; в противном случае поведение не определено
и предоставляет эти примеры:
i = v[i ++]; / / the behavior is undefined
i = ++ i + 1; / / the behavior is undefined
В C ++ 11 и C11 у нас есть одно существенное отличие, которое кроется в Последовательность операторов присваивания в выражениях C11 что является следующим:
i = ++i + 1;
Это связано с тем, что предварительное увеличение именующий в C ++ 11, но не в C11, хотя правила последовательности одинаковы.
У нас есть большая разница в областях, которые не имеют ничего общего с точками последовательности:
Вероятно, есть еще много примеров, но это те, о которых я писал ранее.