этот код c все еще не определенного вывода? - PullRequest
2 голосов
/ 12 декабря 2010

Я читал C Traps and Pitfalls и читал, что следующий код может работать в некоторых реализациях и не работать в других из-за неопределенного порядка = и ++. Это все еще верно для C?

int i = 0;
while (i < n)
    y[i] = x[i++];

Если это так, это действительно невероятно.

Ответы [ 5 ]

5 голосов
/ 12 декабря 2010

Ничего невероятного.Довольно определенное неопределенное поведение.Узнайте больше о точках последовательности .Просто писать как:

int i = 0;
while (i < n)
{
    y[i] = x[i];
    i++;
}

безопаснее и удобочитаемее.

3 голосов
/ 12 декабря 2010

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

Из стандарта языка C ( n1256 ):

6,5 выражений
...
2 Между предыдущей и следующей точкой последовательности объект должен иметь свое сохраненное значение модифицируется не более одного раза путем вычисления выражения. 72) Кроме того, предыдущее значение должен быть прочитан только для определения значения, которое будет сохранено. 73)
...
72) Флаг состояния с плавающей точкой не является объектом и может быть установлен более одного раза в выражении.

73) Этот параграф отображает неопределенные выражения оператора, такие как

    i = ++i + 1;
    a[i++] = i;
позволяя

    i = i + 1;
    a[i] = i;
1 голос
/ 12 декабря 2010

Не особенно удивительно, что этот код имеет неопределенное поведение, потому что он семантически неоднозначен: в y[i], какое значение i предназначено?Значение до приращения или после?(Имейте в виду, что оператор = не указывает, что одна сторона оценивается раньше другой)

0 голосов
/ 12 декабря 2010

Ну, i ++ означает «увеличить i после использования его значения», так что я думаю, что это правильно (ну, я изменил идею, читая другие посты) Скорее я бы сделал:

while((i++) < n)
    y[i] = x[i];
0 голосов
/ 12 декабря 2010

Да, это все еще UB.

§ 1.9p7 В определенных точках последовательности выполнения, называемых точками последовательности, все побочные эффекты предыдущих оценок должны быть завершены, и никаких побочных эффектов последующих оценок не должно быть.(§1.9 / 7)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...