2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Инкременция в Си
Сообщение24.12.2010, 00:37 
Код:
int i=3,j;
j=(++i)+(++i);

Правильно ли я понял, что если нужно найти значение j, мы сначала увеличиваем значение i потом складываем все выражение, т.е. (3+1)+(4+1)=7

 
 
 
 Re: Инкременция в Си
Сообщение24.12.2010, 01:22 
Аватара пользователя
C99 писал(а):
6.5 Expressions
...
2 Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression.⁷²⁾ Furthermore, the prior value
shall be read only to determine the value to be stored.⁷³⁾
...

Так что стандарт говорит, что поведение программы на таких вещах не определено.
GCC здесь выдает 10 - сначала два раза увеличивает, потом складывает.

 
 
 
 Re: Инкременция в Си
Сообщение24.12.2010, 01:25 
Аватара пользователя
В самом деле получается = 9, но я бы не советовал использовать так уродливо в общем-то неплохой язык.
Да, его гибкость столь велика, что он и такую ахинею переварит. Правда, за это многие предпочитают другие языки. Дисциплина должна быть не в языке, а в программисте. Хотя, если вам нравится рассуждать на эту тему - ну кто ж запретит!
С таким же успехом можно выяснять, сколько нематерьяльных духов уместится на конце матерьяльной иглы.
ИМХО, такие упражнения не более чем схоластика.
Но почему именно Си? возьмите другой язык, русский, например. В китайском, я думаю, много ярких примеров. Да и любой из средне-европейских будет не хуже.

-- Пт дек 24, 2010 02:31:30 --

Xaositect в сообщении #390818 писал(а):
C99 писал(а):
6.5 Expressions
...
2 Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression.⁷²⁾ Furthermore, the prior value
shall be read only to determine the value to be stored.⁷³⁾
...

Так что стандарт говорит, что поведение программы на таких вещах не определено.
GCC здесь выдает 10 - сначала два раза увеличивает, потом складывает.

ИМХО, сначала обрабатывается первая скобка (или вторая - это не важно). В процессе ее обработки
i получает значение 4, т.е приходим к выражению j=4+(++i);
дальше - ясно.

 
 
 
 Re: Инкременция в Си
Сообщение24.12.2010, 03:22 
2Day
Цитата:
ИМХО, сначала обрабатывается первая скобка

Проблема не в этом. Дело в том, что оптимизатор имеет право преобразовать это выражение как ему захочется, а значит, результат вычисления такого выражение непредсказуем (т.е. зависит от компилятора). Например, оптимизатор может оставить оба инкремента, в может, заметив, что два подвыражения совпадают, повторно использовать значение первого. В более сложных выражениях (к примеру, умножьте вторые скобки на некоторое число) существенным становится ещё и порядок вычисления подвыражений, который тоже может сильно изменяться компилятором (приоритеты и ассоциативность контролируют синтаксический разбор, а дальше правил нет и все делается в угоду оптимальности кода).

Единственное решение -- не писать такие выражения, в которых значение некоторого объекта модифицируется более одного раза.

-- Пт дек 24, 2010 06:30:10 --

(2mirh)

mirh писал(а):
(3+1)+(4+1)=7

Хорошая арифметика. :)

 
 
 
 Re: Инкременция в Си
Сообщение24.12.2010, 03:35 
Да никто же не говорит, что я такое использую в программах, просто пример увидел :-)

(Оффтоп)

(3+1)+(4+1)=7, действительно неправильно посчитал :-)

 
 
 
 Re: Инкременция в Си
Сообщение25.12.2010, 17:24 
Аватара пользователя
Circiter писал(а):
может, заметив, что два подвыражения совпадают, повторно использовать значение первого
Справедливости ради, такого оптимизатор не должен себе позволять. Всё-таки, тут слишком явные побочные эффекты. А то выражение
Код:
rand()+rand()
возвращало бы только чётные числа.

 
 
 
 Re: Инкременция в Си
Сообщение25.12.2010, 18:43 
Аватара пользователя
worm2 в сообщении #391462 писал(а):
Circiter писал(а):
может, заметив, что два подвыражения совпадают, повторно использовать значение первого
Справедливости ради, такого оптимизатор не должен себе позволять. Всё-таки, тут слишком явные побочные эффекты. А то выражение
Код:
rand()+rand()
возвращало бы только чётные числа.

Или, скажем,
Код:
getc() + getc()

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

 
 
 [ Сообщений: 7 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group