i = i ++ действительно неопределенное поведение?

Возможный дубликат:
Может ли кто-нибудь объяснить эти неопределенные поведения (i = i ++ + ++ i, i = i ++ и т. Д.)

Согласно стандарту c ++,

i = 3; i = i++; 

приведет к неопределенному поведению.

Мы используем термин «неопределенное поведение», если это может привести к более чем одному результату. Но здесь окончательное значение i будет равно 4 независимо от того, какой порядок оценки, так разве это не следует называть «неуказанным поведением»?

Фраза «… окончательное значение i будет 4 независимо от того, какой порядок оценки …» является неправильным. Компилятор может испустить эквивалент этого:

 i = 3; int tmp = i; ++i; i = tmp; 

или это:

 i = 3; ++i; i = i - 1; 

или это:

 i = 3; i = i; ++i; 

Что касается определений терминов, если бы ответ был гарантирован 4, это не было бы неопределенным или неопределенным поведением, это определяло бы поведение.

Как бы то ни было, это неопределенное поведение в соответствии со стандартом ( Википедия ), поэтому он даже свободен:

 i = 3; system("sudo rm -rf /"); // DO NOT TRY THIS AT HOME … OR AT WORK … OR ANYWHERE. 

Нет, мы не используем термин «неопределенное поведение», когда оно может просто привести к более чем одному арифметическому результату. Когда поведение ограничено различными арифметическими результатами (или, в более общем плане, некоторым набором outlookируемых результатов), его обычно называют неуказанным поведением.

Неопределенное поведение означает совершенно непредсказуемые и неограниченные последствия, такие как форматирование жесткого диска на вашем компьютере или просто сбой вашей программы. И i = i++ – это неопределенное поведение.

Там, где у вас появилась идея, что i должен быть 4 в этом случае, неясно. На языке C ++ абсолютно нет ничего, что позволило бы вам прийти к такому выводу.

В C, а также в C ++ порядок любой операции между двумя точками последовательности полностью зависит от компилятора и не может зависеть. Стандарт определяет список вещей, которые составляют точки последовательности, из памяти это

  1. точка с запятой после заявления
  2. оператор запятой
  3. оценка всех аргументов функции перед вызовом функции
  4. && и || операнд

Взглянув на страницу в wikipedia, списки более полные и более подробно описаны. Точки последовательности являются чрезвычайно важной концепцией, и если вы еще не знаете, что это значит, вы получите большую пользу, изучив ее сразу.

i =, и i ++ – оба побочных эффекта, которые изменяют i.

i ++ не означает, что i только увеличивается после того, как весь оператор оценивается, просто чтобы было прочитано текущее значение i. Таким образом, назначение и приращение могут происходить в любом порядке.

1. Нет, результат будет отличаться в зависимости от порядка оценки. Границы оценки между приращением и присваиванием отсутствуют, поэтому приращение может быть выполнено до или после назначения. Рассмотрим это поведение:

 load i into CX copy CX to DX increase DX store DX in i store CX in i 

В результате i содержит 3 , а не 4 .

Для сравнения, в C # существует граница оценки между evaulation выражения и присваиванием, поэтому результат всегда будет 3 .

2. Даже если точное поведение не указано, спецификация очень понятна в отношении того, что она покрывает и что она не охватывает. Поведение указано как неопределенное, оно не указано.

Чтобы ответить на ваши вопросы:

  1. Я думаю, что «неопределенное поведение» означает, что разработчик компилятора / языка свободен делать все, что он считает лучшим, и не может привести к нескольким результатам.
  2. Потому что это не неуказано . Четко указано, что его поведение не определено .

Не стоит печатать i = i ++, когда вы просто можете ввести i ++.

  • В C # следует ли использовать string.Empty или String.Empty или "" для инициализации строки?
  • Какие библиотеки Boost предназначены только для заголовков?
  • Разность C # между == и Equals ()
  • C # /. NET инструмент анализа для поиска условий гонки / тупиков
  • Получить строковое имя свойства, используя reflection
  • Почему C ++ STL настолько сильно зависит от шаблонов? (а не на * интерфейсах *)
  • Является ли C # действительно медленнее, чем C ++?
  • Строка ввода не была в правильном формате
  • Как я могу создать решение программно на C #?
  • Что такое EOF на языке программирования C?
  • JSON.Net: принудительная сериализация всех частных полей и всех полей в подclassах
  • Давайте будем гением компьютера.