реклама на сайте
подробности

 
 
6 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> фича компиляторв, инкремент переменной
zltigo
сообщение May 11 2007, 17:48
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Oldring @ May 11 2007, 18:37) *
В выражении ++i + i ....

Таки да! Имеет место быть неопределенность исполнения side effect от оператора ++ по отношению к операции сложения. Взгляд замылил префиксный инкремент sad.gif, который на самом деле не имеет отношения к делу.
Если вернуться к первоисточнику, то в этом конкретном случае ничего принципиально не разрешимого для компилятора нет, однако смягчения правил игры установленные стандартом в виде виде sequence point позволяют ему не разбираться с этими заморочками. Совершенно правильный подход к делу, поскольку заумные выражения усложняет жизнь компилятору и на самом деле ничего не дают програмисту.
С другой стороны никто не может запретить разбирать и более сложные конструкции в этом случае он (Watcom, например) спокойно жует и такие перлы и выдает правильное значение 14. Те компиляторы, которые не разбирают - ругаются (IAR). Те компиляторы, которые не разбирают, молчат и выдают произвольное значение - бяки smile.gif.

Цитата(vromanov @ May 11 2007, 19:08) *
Удивительно, что столь очевидная вещь собрала столько сломанных копий.

Где Вы копья увидели? А вещь не очевидная, если считать очевидным не использование такой дури в явном виде ни при каких условиях smile.gif.

Сообщение отредактировал zltigo - May 11 2007, 18:52


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение May 11 2007, 17:54
Сообщение #17


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
x = ++i + ++i;
cranky.gif
Это в китайских исходниках такое нашли?
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 18:04
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Ivan_Kov @ May 11 2007, 14:33) *
Проблема стара как "С"...
Скобки используйте и все дела.

Скобки не определяют Sequence points и не помогут ничем.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
vromanov
сообщение May 11 2007, 18:54
Сообщение #19


Участник
*

Группа: Новичок
Сообщений: 70
Регистрация: 27-03-07
Пользователь №: 26 533



Цитата(zltigo @ May 11 2007, 21:48) *
Где Вы копья увидели? А вещь не очевидная, если считать очевидным не использование такой дури в явном виде ни при каких условиях smile.gif.

По всем сообществам разбирают эту строчку. И куча народа дже после правильного ответа продолжают что-то придумывать, строить какие-то предположения..
Еще и колеги на работе по аське достали этим выражением.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 19:03
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(vromanov @ May 11 2007, 21:54) *
И куча народа дже после правильного ответа продолжают что-то придумывать, строить какие-то предположения..

Никаких придумок - либо компилятор должен выдать 14, либо ссылаясь на биль о правах компиляторов отказаться отвечать на этот вопрос допущения стандарта послать такое выражения подальше.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
lebiga
сообщение May 11 2007, 19:57
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 22-06-06
Из: Киев
Пользователь №: 18 292



Цитата(vromanov @ May 11 2007, 20:08) *
Удивительно, что столь очевидная вещь собрала столько сломанных копий. Есть кучу куда более прикольных особеностей в с++ smile.gif

//--------------------------------------

Когда-то полдня убил на глюк ИАРА. Код ниже работал в MCС18 (пик), а в ИАРЕ (4.30, ARM) нет.

unsigned char c;
char* cr;

выше инициализация credential;

while((c = *credential) != '\r') // Advance until \r (end of credentials)
credential++;
*credential = '\0'; // NULL char to replace \r.

//---------------------------
Пока не заменил на:

do { if(*credential=='\r') break;
credential++;
}while(1);
credential++;
*credential = '\0'; // NULL char to replace \r.

Причем игрался с оптимизациями - не помогало. Вылетало за пределы массивов.

Сообщение отредактировал lebiga - May 11 2007, 20:01
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 11 2007, 19:59
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(zltigo @ May 11 2007, 23:03) *
Никаких придумок - либо компилятор должен выдать 14, либо ссылаясь на биль о правах компиляторов отказаться отвечать на этот вопрос допущения стандарта послать такое выражения подальше.


Почему 14?
IMHO правильное значение может быть 12, 13, но никак не 14. biggrin.gif


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
vromanov
сообщение May 11 2007, 20:02
Сообщение #23


Участник
*

Группа: Новичок
Сообщений: 70
Регистрация: 27-03-07
Пользователь №: 26 533



Цитата(zltigo @ May 11 2007, 23:03) *
Никаких придумок - либо компилятор должен выдать 14, либо ссылаясь на биль о правах компиляторов отказаться отвечать на этот вопрос допущения стандарта послать такое выражения подальше.

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


Цитата(lebiga @ May 11 2007, 23:57) *
//--------------------------------------

Когда-то полдня убил на глюк ИАРА. Код ниже работал в MCС18 (пик), а в ИАРЕ (4.30, ARM) нет.

А вот это уже 100% глюк компилятора. Точнее оптимизатора.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 20:19
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(vromanov @ May 11 2007, 23:02) *
Компилятор ничего не должен..
В стандарте не написано, что он должен посылать такое выражение.

Нет, если он взялся разбирать это выражение, то он должен руководствуясь общими правилами выполнения операций и их приоритетов выдать такое значение. А вот отказаться имеет право и в случае отказа естествено не должен ничего и ни кому.




Цитата(Oldring @ May 11 2007, 22:59) *
IMHO правильное значение может быть 12, 13, но никак не 14. biggrin.gif

Выполняется инкремент i, как самый приоритетный (левый или правый на Ваше усмотрение smile.gif )
Затем второй инкремент i, потом сложение, как самая неприоритетная операция.
Выполнены все три операции в порядке приоритетов. Все.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 11 2007, 21:07
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(zltigo @ May 12 2007, 00:19) *
Нет, если он взялся разбирать это выражение, то он должен руководствуясь общими правилами выполнения операций и их приоритетов выдать такое значение. А вот отказаться имеет право и в случае отказа естествено не должен ничего и ни кому.


http://electronix.ru/forum/index.php?s=&am...st&p=249062

Цитата
Possible undefined behavior ranges from ignoring the situation completely with unpredictable
results
, to behaving during translation or program execution in a documented manner characteristic of the
environment (with or without the issuance of a diagnostic message), to terminating a translation or
execution (with the issuance of a diagnostic message).


Это цитата из стандарта. На русский переводить не нужно? Как видите, компилятор никому ничего не должен, все остальное - фантазии.

Цитата(zltigo @ May 12 2007, 00:19) *
Выполняется инкремент i, как самый приоритетный (левый или правый на Ваше усмотрение smile.gif )
Затем второй инкремент i, потом сложение, как самая неприоритетная операция.
Выполнены все три операции в порядке приоритетов. Все.


Да, именно так. Пусть аргументы '+' вычисляются справа налево wink.gif Сначала считывается значение правого i (5) прибавляем 1, записываем значение правого i. Запоминаем результат правого подвыражения (6). Затем считываем значение левого i (6), прибавляем 1, сохраняем новое значение i, запоминаем результат левого подвыражения (7). Теперь к результату правого подвыражения (6) прибавляем результат левого подвыражения (7) и в результате получаем 13.

Альтернатива - когда результаты преинкремента прописываются в переменные в конце вычисления выражения (имеют право - точка сохранения результатов однозначно не определена). В этом случае результат двух подвыражений будет 6, и их сумма будет 12.

А вот как получить 14 - не понимаю biggrin.gif


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 11 2007, 21:57
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Oldring @ May 12 2007, 00:07) *
Это цитата из стандарта. На русский переводить не нужно? Как видите, компилятор никому ничего не должен, все остальное - фантазии.

Переводить не нужно. Может вам мой предыдущий пост на английский перевести? Или постараетесь мой русский язык понять? Повторять не вижу смысла.
Цитата
Запоминаем результат правого подвыражения (6)

Вот 'запоминаем' это и есть чистейшей воды фантазии. С какого бодуна компилятор будет заводить промежуточную переменную-дубль для запоминания? Только если у него совсем крышу снесло.
Цитата
Альтернатива - когда результаты преинкремента прописываются в переменные в конце вычисления выражения (имеют право - точка сохранения результатов однозначно не определена). В этом случае результат двух подвыражений будет 6, и их сумма будет 12.

Это или инкремент суммирование инкремент суммы с тем-же результатом - имеет право, только если это он сделает без warnig я не пойму такой поступок.
Цитата
А вот как получить 14 - не понимаю biggrin.gif

Тогда перечитайте, вдруг поймете. Если не поймете - можете поискать компилятор, который без warning выдаст результат отличный от 14. Может удастся принять, как даденность smile.gif. Вдруг найдете - сообщите, что-бы вдруг я случайно не стал пользовать небрежно писанный компилятор.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 12 2007, 07:23
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(zltigo @ May 12 2007, 01:57) *
Переводить не нужно. Может вам мой предыдущий пост на английский перевести? Или постараетесь мой русский язык понять? Повторять не вижу смысла.


А что - переведите, будет любопытно. biggrin.gif
Вот только это все равно будет Ваше личное мнение, пусть и на английском языке, в отличие от процитированных мною требований стандарта.

Цитата(zltigo @ May 12 2007, 01:57) *
Вот 'запоминаем' это и есть чистейшей воды фантазии. С какого бодуна компилятор будет заводить промежуточную переменную-дубль для запоминания? Только если у него совсем крышу снесло.


По правилам формальной семантики выражений языка С (так как мы говорим о "правильности" выражений - мы на время забываем, что такое выражение в целом - undefined bihavior). '+' суммирует результаты своих левого и правого подвыражений. С какого бодуна результат первого подвыражения изменяется после его вычисления?

Цитата(zltigo @ May 12 2007, 01:57) *
Тогда перечитайте, вдруг поймете. Если не поймете - можете поискать компилятор, который без warning выдаст результат отличный от 14. Может удастся принять, как даденность smile.gif. Вдруг найдете - сообщите, что-бы вдруг я случайно не стал пользовать небрежно писанный компилятор.


Я-то как раз понимаю, как компилятор получает такой результат. У многих компиляторов один из промежуточных этапов компиляции - получение трехадресного кода. При этом разработчики компиляторов, помня правило, процитированное мною первым в первом моем посте, полагаются на то, что переменная i второй раз в одном и том же выражении не изменится, и в ней можно сохранить промежуточный результат подвыражения вместо заведения еще одной промежуточной переменной. Такое предположение компилятора в данном случае является ошибочным. То есть такое поведение - побочный эффект, допускаемый стандартом как undefined bihavior, но никак не "правильное" поведение компилятора. biggrin.gif

P.S. Что касается "небрежно написанных компиляторов" - есть такая русская пословица, про зеркало. Компилятор может выдавать что угодно в подобных выражениях. Делать или нет специальный анализ выражения для генерации предупреждений в таких случаях - это выбор разработчиков компиляторов, тем более, что во многих случаях (с указателями) компилятор просто не может знать, что два подвыражения модифицируют один объект. Поэтому лучше так не пишите, а если пишите - то ничего не требуйте от компилятора. Язык С, действительно, налагает довольно высокие требования на квалификацию программиста в части неиспользования некоторых конструкций.


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 12 2007, 08:31
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Oldring @ May 12 2007, 10:23) *
Я-то как раз понимаю, как компилятор получает такой результат....

Я тоже. Только это внутреннее дело компилятора, как он обрабатывает неправильные с точки зрения стандарта (определяющего минимальные требования к компилятору) конструкции. То, что k=++i + ++i; компилятор имеет право не заморачиваясь на специальные анализы тупо на автомате разбирать и получать непредсказуемый результат это понятно. И никто никогда против этого не возражал.

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

Выражение k=++i + ++i; являсь совершенно диким, тем не менее поддается однозначной разборке согласно основополагающим правилам операций и их приоритетов. Про трудности компиляции такого и _правильное_ решение стандарта разрешить не заморачиваться с такой разборкой все ясно.

Цитата
Что касается "небрежно написанных компиляторов" - есть такая русская пословица, про зеркало.

Это не ко мне. Я не писал, не пишу и не буду писать подобных выражений, но тем не менее, если вдруг комилятор позволит себе не выдав предупреждение в таком выражении выдать значение отличное от 14, то это меня насторожит и приведет к некоторому недоверию к такому компилятору, поскольку он чего-то не поняв позволил себе меня не предупредить.
Цитата
Делать или нет специальный анализ выражения для генерации предупреждений в таких случаях - это выбор разработчиков компиляторов

Это их право. Только у меня тоже есть право smile.gif не использовать такие компиляторы smile.gif.
Поскольку сегодня выходной день, то я провел маленький тест используемых мною в повседневной жизни компиляторов.
OpenWatcom, GCC, Borland не возразили и выдали правильный результат.
IAR, VisualDSP - выдали предупреждение.
Все это с учетом того, что warnigs я всегда по максимуму активизирую и без оптимизации компиляцию не пользую.
Результат меня полностью удовлетворил - по поводу разборки этой дури у меня претензий к используемым мною компиляторам нет и с их разработчиками у меня коннсенсус smile.gif.

Цитата
Поэтому лучше так не пишите, а если пишете - то ничего не требуйте от компилятора.

К чему это адресное обращение? Я призывал так писать???

P.S.
Пожалуй по четвертому кругу я больше не пойду изъясняться по проблемам k=++i + ++i;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 12 2007, 08:45
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(zltigo @ May 12 2007, 12:31) *
Выражение k=++i + ++i; являсь совершенно диким, тем не менее поддается однозначной разборке согласно основополагающим правилам операций и их приоритетов. Про трудности компиляции такого и _правильное_ решение стандарта разрешить не заморачиваться с такой разборкой все ясно.


Ну так приведите свой правильный разбор. Я свой привел, приводящий к 12 или 13. Я утверждаю, что 14 - это неправильный результат исходя из семантики операций.

Цитата(zltigo @ May 12 2007, 12:31) *
К чему это адресное обращение? Я призывал так писать???


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


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 12 2007, 09:26
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Oldring @ May 12 2007, 11:45) *
Ну так приведите свой правильный разбор.

Я приводил.
Цитата
Я свой привел, приводящий к 12 или 13.

Приводили, но не с точки зрения базовых правил а с точки зрения как может быть построена разборка выражения в потрохах компилятора. Что позволяет объяснить, почему появляется неправильный результат и почему стандарт не требует разбирать такую ерунду. Но все это не имеет отношения к пользователю компилятора написавшего дурацкое, сложно разбираемое компилятором (если он за это возьмется!), хреново оптимизируемое и трудно понимаемое человеком, но вполне однозначо трактуемое выражение - "берем одну едиственную переменную, инкрементируем один раз, инкрементируем второй раз, прибавляем к ней ее-же значение.
Цитата
В ответ на Ваше утверждение, что для Вас имеет принципиальное значение, какой результат выдается для этого выражения. Если я Вас неправильно понял - тогда извините.

Про "принципиальное значение" я ни сном ни духом не поминал. Повторяю - выдаваемый результат лично для меня имеет некоторое (а отнюдь не принципиальное) значение только в плане оценки компилятора и только в том единственном случае, когда он не выдав предупреждения выдал результат отличный от 14. В проведенных тестах я даже не смотрел на результат у компиляторов которые выдали warning-и. Во настолько он для меня имеет "принципиальное значение" smile.gif
Извиняю.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

6 страниц V  < 1 2 3 4 > » 
Reply to this topicStart new topic
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 21:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.01527 секунд с 7
ELECTRONIX ©2004-2016