В некоторых ответах / комментариях обсуждается значение «неопределенного поведения» и делает ли программа недействительной. Поэтому я публикую этот довольно длинный ответ с подробным описанием того, что говорится в стандарте, с некоторыми примечаниями. Надеюсь, это не слишком скучно ...
Указанные биты стандарта взяты из текущего стандарта C ++ (ISO / IEC 14882: 2003). В стандарте C есть аналогичная формулировка.
В соответствии со стандартом C ++ изменение значения более одного раза в наборе точек последовательности приводит к неопределенному поведению (раздел 5, параграф 4):
Если не указано иное, порядок
оценка операндов индивида
операторы и подвыражения
отдельные выражения и порядок
в котором побочные эффекты имеют место, является
не указано.53) Между предыдущими
и следующая последовательность указывает скаляр
объект должен иметь свое сохраненное значение
модифицируется не более одного раза
оценка выражения.
Кроме того, предыдущее значение должно быть
доступ только для определения значения
быть сохраненным. Требования этого
пункт должен быть соблюден для каждого
допустимый порядок
подвыражения полного выражения;
в противном случае поведение не определено.
[Пример:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
- конец примера]
Обратите внимание, что второй пример "i = 7, i++, i++;
" определен, поскольку оператор запятой является точкой последовательности.
Вот что в стандарте C ++ означает «неопределенное поведение»:
1.3.12 неопределенное поведение [defns.undefined]
поведение, которое может возникнуть при использовании ошибочной программной конструкции или ошибочных данных, для которых это
Международный стандарт не предъявляет никаких требований. Неопределенное поведение также может ожидаться, когда это
Международный стандарт опускает описание любого явного определения поведения. [Примечание: допустимо неопределенное
поведение варьируется от полного игнорирования ситуации с непредсказуемыми результатами до поведения во время
перевод или выполнение программы документированным образом, характерным для среды (с или без
выдача диагностического сообщения), чтобы прекратить перевод или выполнение (с выдачей
диагностическое сообщение). Многие ошибочные программные конструкции не порождают неопределенное поведение; они должны быть диагностированы. ]
Другими словами, компилятор может делать все, что захочет, включая
- выплевывая сообщение об ошибке,
- что-то делает реализацию, определенную и задокументированную,
- с совершенно непредсказуемыми результатами
Второй пункт охватывает языковые расширения, которые есть у большинства компиляторов, но, конечно, они не определены в стандарте.
Так что я предполагаю, что строго говоря, что-то, что демонстрирует неопределенное поведение, не является «незаконным», но по моему опыту, когда в программе на C / C ++ было что-то, демонстрирующее «неопределенное поведение» (если это не расширение) - это ошибка , Я думаю, что называть такую конструкцию незаконной - не смущать, не вводить в заблуждение и не вводить в заблуждение.
Кроме того, я думаю, что попытка объяснить, что делает компилятор для достижения значения 14, не особенно полезна, так как это упускает смысл. Компилятор может делать почти все; на самом деле, вполне вероятно, что компилятор может достичь другого результата, когда он запускается с использованием разных параметров оптимизации (или может привести к сбою кода - кто знает?).
Для тех, кому нужны дополнительные ссылки или обращение к власти, вот несколько указателей:
Длинный, длинный ответ Стива Саммита (сопровождающего часто задаваемые вопросы о comp.lang.c) по этой теме с 1995 года:
Вот что говорит Бьярн Страуструп по этому вопросу:
Сноска : стандарт C ++ использует слово «незаконно» ровно один раз - при описании различий между C ++ и Standard C в отношении использования static
или extern
с объявлениями типов.