2013-11-11 4 views
4

При чтении Язык программирования C, я заметил в приоритете порядке раздела оценки говорится, что»... вызовы функций, вложенные операторы присваивания и приращения и уменьшения вызывают "побочные эффекты"...".Вложенные операторы присваивания и побочные эффекты

Я пытаюсь найти несколько примеров вложенных операторов присваивания, которые приводят к неопределенному поведению. В книге говорится следующее является нормально:

int nl, nw, nc; 
nl = nw = nc = 0; 

в этом nl, nw и nc все будут назначены 0.

Затем я наткнулся на this, который гласит:

x = y = y = z/3;  

ли не "рекомендуемое". Итак, мой вопрос: что может пойти не так с этим утверждением? Назначения ассоциируют с правой стороны, так что утверждение будет эквивалентно:

x = (y = (y = z/3));  

Ко мне, кажется, довольно ясно, что y = z/3 и x = z/3. Итак, если это так, то может ли кто-нибудь дать мне пример вложенного оператора присваивания, который может привести к неопределенному поведению, а если нет, можете ли вы объяснить, почему предыдущий оператор не определен.

ответ

4

Операторы присваивания не ограничиваются одной переменной. Помимо прочего, вы можете назначить элементы массива.

Рассмотрим пример вложенного присваивания:

int a[] = {100, 200}; 
a[a[1]] = a[1] = 0; 

, если оценивать последовательность заданий, он должен работать следующим образом:

a[1] = 0 

После этого задания a выглядит следующим образом: {100, 0}

a[a[1]] = 0 

Зная в a[1] равен нулю, это то же самое, как a[0] = 0, так что массив должен выглядеть следующим образом: {0, 0}

Однако, проблема заключается в том, что вы теперь ставку на то, что побочный эффект a[1] = 0 завершена к тому времени, перейдите к следующему назначению: иначе вы назначаете ноль a[100], который проходит мимо конца массива.

Поскольку порядок завершения побочных эффектов не определяется в отсутствие sequence points, это неопределенное поведение.

1

http://c-faq.com/expr/seqpoints.html имеет несколько моментов, которые касаются вашего вопроса.В частности:

В то время как y = y, вероятно, хорошо в

x = y = y = z/3; 

Выражение как

y = y++ 

не определен, так как значение y изменяется дважды до точки последовательности.

1

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

x = y = y++; 

Они не о том, что все вложенные задания вызывают неопределенное поведение, но только что вы должны избегать их всех, чтобы избежать возможно, используя те, делать. Это скорее рекомендация по стилю.

+0

В 'x = y = y = z/3;', не является ли значение 'y' технически установленным дважды между точками последовательности? Кажется, я понимаю суть того, что вы говорите. – Justin

+1

Но в обоих случаях оно устанавливается одинаково, поэтому порядок, в котором они происходят, несуществен. – Barmar

Смежные вопросы