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

 
 
> фича компиляторв, инкремент переменной
zhevak
сообщение May 11 2007, 11:25
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



На форуме программистов (здесь http://www.rsdn.ru/Forum/?mid=2481623) с пацанами сейчас подняли интересную тему. Думаю, что си-шникам тоже следует остерегаться подобного кода. В двух словах проблема состоит в том, как компилятор должен понимать оператор инкремента.



int i;
int x;

i = 5;
x = ++i + ++i;



Чему в результате будет равно х ?

Прикол в том, что MS VC++ 6.0 и VC++.NET дают результат, равный 14. Майкрософтовский C# и IAR говорят, что х = 13. А более всего удивил Watcom -- у него результат зависит от того, включена-ли оптимизация или нет... 07.gif

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

Вечером дома, попробую еще в CodeVision эту фичу покрутить.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
vetal
сообщение May 12 2007, 11:11
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 2 095
Регистрация: 27-08-04
Из: Россия, СПб
Пользователь №: 553



Потому и "undefined bihavior", что по моему мнению оператор + складывает 2 ячейки памяти с адресом I, а по вашему он заводит дополнительную переменную. Тут всё и кроется))
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 12 2007, 12:23
Сообщение #3


Гуру
******

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



Цитата(vetal @ May 12 2007, 15:11) *
Потому и "undefined bihavior", что по моему мнению оператор + складывает 2 ячейки памяти с адресом I, а по вашему он заводит дополнительную переменную. Тут всё и кроется))


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

Ваше мнение о том, "что оператор + складывает 2 ячейки памяти с адресом i" противоречит утверждению из стандарта, что результат вычисления ++i не есть lvalue. Так что такую интерпретацию принять не могу как "правильную" smile.gif


Цитата(zltigo @ May 12 2007, 15:48) *
Вся эта бодяга действительно отдана на откуп компилятору в зависимости от платформы. Но что интересно - в результате реального эксперимента все компиляторы для x86 платформы выдали тот самый результат, а под ARM и BF выдали warning - не смогли на штатном механизме обеспечить?
Интересный такой нюанс. Надо будет GNU на не на x86 платформе спытать.


arm-elf-gcc версии 4.1.1 выдает 13. cool.gif


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


Гуру
******

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



Цитата(Oldring @ May 12 2007, 15:23) *
arm-elf-gcc версии 4.1.1 выдает 13. cool.gif

Молча?


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


Гуру
******

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



Цитата(zltigo @ May 12 2007, 17:05) *
Молча?


По умолчанию - да.

В программе, приведенной ниже, с ключем -Wsequence-point выдается предупреждение "warning: operation on 'i' may be undefined" внутри main(), но не внутри f(). В обоих случаях - 13.

Код
int f( int* p1, int* p2 )
{
    return ++(*p1) + ++(*p2);
}

int main( void )
{
    int i;
    int x1, x2;

    i = 5;
    x1 = ++i + ++i;

    i = 5;
    x2 = f( &i, &i );

    return x2;
}


P.S. С включенной оптимизацией -O3 main своится к возврату 13.


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


Гуру
******

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



Цитата(Oldring @ May 12 2007, 16:14) *
В программе, приведенной ниже, с ключем -Wsequence-point выдается предупреждение "warning: operation on 'i' may be undefined" внутри main(), но не внутри f(). В обоих случаях - 13.

Ну про f() это естественно правильно - по другому было-бы крайне странно. С main() выдал warning расписавшись в непонятках - тоже каой-же после этого спрос.

Зксперименировал для начала с OpenWatcom...
Цитата
P.S. С включенной оптимизацией -O3 main своится к возврату 13.

Аналогично. C приличными оптимизациями все сводится к smile.gif
Код
    push      0000000eH
    push      offset FLAT:L$402
    call      near ptr FLAT:printf_
    add       esp,00000008H
    ret

Пришлось извне передавать.
Код
void dummy( int i )
{
int k = ++i + ++i;
    printf( "k=%i\r", k );
}

Это вариант с разнообразными оптимизаторами:
Код
    add       eax,00000002H
    add       eax,eax
    push      eax
    push      offset FLAT:L$402
    call      near ptr FLAT:printf_
    add       esp,00000008H
    ret

и вообще без оптимизации:
Код
    push      00000030H
    call      near ptr FLAT:__CHK
    push      ebx
    push      ecx
    push      edx
    push      esi
    push      edi
    push      ebp
    mov       ebp,esp
    sub       esp,0000000cH
    mov       dword ptr -0cH[ebp],eax
    inc       dword ptr -0cH[ebp]
    inc       dword ptr -0cH[ebp]
    mov       eax,dword ptr -0cH[ebp]
    add       eax,dword ptr -0cH[ebp]
    mov       dword ptr -4H[ebp],eax
    push      dword ptr -4H[ebp]
    mov       eax,offset FLAT:L$450
    push      eax
    call      near ptr FLAT:printf_
    add       esp,00000008H
    mov       esp,ebp
    pop       ebp
    pop       edi
    pop       esi
    pop       edx
    pop       ecx
    pop       ebx
    ret

Но при любых уровнях оптимизации "неизменно превосходный результат". warnin-ов нет. Причем, что действительно интересно даже в вырожденном случае с тупым возвратом значения , где уже все заранее решено - 14.



Цитата(vetal @ May 12 2007, 16:09) *
И говорит что так делать нельзя.

В обоих случаях оптимизации говорит нельзя?


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


Гуру
******

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



Цитата(zltigo @ May 12 2007, 18:14) *
Но при любых уровнях оптимизации "неизменно превосходный результат". warnin-ов нет. Причем, что действительно интересно даже в вырожденном случае с тупым возвратом значения , где уже все заранее решено - 14.


В любом случае, это не есть доказательство "правильности" значения 14.

Цитата(zltigo @ May 12 2007, 18:14) *
Ну про f() это естественно правильно - по другому было-бы крайне странно. С main() выдал warning расписавшись в непонятках - тоже каой-же после этого спрос.


gcc на x86 неизменно возвращает 14. в том числе, из f() smile.gif


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


Гуру
******

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



Цитата(Oldring @ May 12 2007, 17:38) *
В любом случае, это не есть доказательство "правильности" значения 14.

Ну скажем так, это некий результат полученный на нескольких компиляторах, без сопутствующего warning (типа не сомневались в результате?). Все другие компиляторы выдающие отличный результат неизменно генерили при этом warning. Как это можно истолковать?
А с учетом того, что авторы компиляторов разбираюся в этом скорее всего лучше, чем все здесь собравшиеся вместе взятые?
Цитата
gcc на x86 неизменно возвращает 14. в том числе, из f() smile.gif

Я мельком глянул на f() - естественно ошибся sad.gif.


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


Гуру
******

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



Цитата(zltigo @ May 12 2007, 18:51) *
Ну скажем так, это некий результат полученный на нескольких компиляторах, без сопутствующего warning (типа не сомневались в результате?). Все другие компиляторы выдающие отличный результат неизменно генерили при этом warning. Как это можно истолковать?
А с учетом того, что авторы компиляторов разбираюся в этом скорее всего лучше, чем все здесь собравшиеся вместе взятые?


Как истолковать? Как невыдачу предупреждения на undefined bihavior код. biggrin.gif

То, что "А с учетом того, что авторы компиляторов разбираюся в этом скорее всего лучше, чем все здесь собравшиеся вместе взятые" - утверждение просто смешное. Компилятор - не такая уж непостижимая для понимания программа. Очень много народу писало разнообразные компиляторы - ну разве что не такие оптимизирующие.

Вы никогда не читали учебники по устройству компиляторов? Вот, например, из недавних был издан на русском языке в 2001 году. "Компиляторы. Принципы, технологии, инструменты". Ахо, Сети, Ульман. Авторы, кстати - классики по теории компиляции. Очень рекомендую.


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


Гуру
******

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



Цитата(Oldring @ May 12 2007, 18:14) *
Как истолковать? Как невыдачу предупреждения на undefined bihavior код. biggrin.gif

И при этом выдачу предупреждения при компиляции компилятором из этой-же линейки для другой платформы smile.gif??? И выдачу предупреждения undefined bihavior этим-же компилятром для другого выражения? И все это с грубыми, по Вашему мнению нарушениями?
Цитата
Компилятор - не такая уж непостижимая для понимания программа.

Компилятор вполне постижимая - сам писал в свое время со своего-же тестового языка smile.gif для Z80 target. Проблема здесь в толковании правил и обеспечении соблюдения неписанных договоренностей.


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


Гуру
******

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



Цитата(zltigo @ May 12 2007, 19:42) *
И при этом выдачу предупреждения при компиляции компилятором из этой-же линейки для другой платформы smile.gif??? И выдачу предупреждения undefined bihavior этим-же компилятром для другого выражения? И все это с грубыми, по Вашему мнению нарушениями?

Компилятор вполне постижимая - сам писал в свое время со своего-же тестового языка smile.gif для Z80 target. Проблема здесь в толковании правил и обеспечении соблюдения неписанных договоренностей.


Я считаю, что все, что касается правил компиляции - изложено в стандарте языка. Там нет ничего непостижимого. Стандарт - это закон. Поэтому доводы "это непостижимо" не приемлю, извините.

Я Вам привел цитаты из стандарта и разъяснил, как именно значение 14 противоречит понятию "правильности" результата этого выражения если даже забыть на время об ограничении по поводу undefined bihavior для выражения в целом. Вы можете привести какие-либо аргументы в поддержку своей позиции (утверждений об "однозначности разбора" и о "правильности" результата 14) кроме того, что некоторые космпиляторы не выдают предупреждение, выдавая в результате 14?

Ну и кроме того, хочу привести последний аргумент. То, что часть компиляторов выдает 13 (имеют полное право), а часть - 14, не означает ли, что компиляторы, не выдающие на такой код предупреждение, просто имеют более слабую диагностику по сравнению с теми, которые выдают такую диагностику?


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- zhevak   фича компиляторв   May 11 2007, 11:25
- - vromanov   Тут все просто. По стандарту результат исполнения ...   May 11 2007, 11:29
|- - Oldring   Цитата(vromanov @ May 11 2007, 15:29) Тут...   May 11 2007, 15:37
|- - zltigo   Цитата(Oldring @ May 11 2007, 18:37) В вы...   May 11 2007, 17:48
|- - vromanov   Цитата(zltigo @ May 11 2007, 21:48) Где В...   May 11 2007, 18:54
|- - zltigo   Цитата(vromanov @ May 11 2007, 21:54) И к...   May 11 2007, 19:03
|- - Oldring   Цитата(zltigo @ May 11 2007, 23:03) Никак...   May 11 2007, 19:59
||- - PrSt   Цитата(Oldring @ May 11 2007, 22:59) Поче...   May 13 2007, 14:08
||- - lebiga   Пора рассматривать известную шутку Ричи и Керниган...   May 13 2007, 16:03
||- - zhevak   Цитата... разбиваем как это делает компилятор temp...   May 14 2007, 00:04
||- - Oldring   Цитата(zhevak @ May 14 2007, 04:04) Отсюд...   May 14 2007, 03:31
|- - vromanov   Цитата(zltigo @ May 11 2007, 23:03) Никак...   May 11 2007, 20:02
|- - zltigo   Цитата(vromanov @ May 11 2007, 23:02) Ком...   May 11 2007, 20:19
|- - Oldring   Цитата(zltigo @ May 12 2007, 00:19) Нет, ...   May 11 2007, 21:07
|- - zltigo   Цитата(Oldring @ May 12 2007, 00:07) Это ...   May 11 2007, 21:57
|- - Oldring   Цитата(zltigo @ May 12 2007, 01:57) Перев...   May 12 2007, 07:23
|- - zltigo   Цитата(Oldring @ May 12 2007, 10:23) Я-то...   May 12 2007, 08:31
|- - Oldring   Цитата(zltigo @ May 12 2007, 12:31) Выраж...   May 12 2007, 08:45
|- - zltigo   Цитата(Oldring @ May 12 2007, 11:45) Ну т...   May 12 2007, 09:26
|- - Oldring   Цитата(zltigo @ May 12 2007, 13:26) Я при...   May 12 2007, 09:34
|- - zltigo   Цитата(Oldring @ May 12 2007, 12:34) Не в...   May 12 2007, 09:36
|- - Oldring   Цитата(zltigo @ May 12 2007, 13:36) Жаль....   May 12 2007, 09:56
- - Ivan_Kov   Проблема стара как "С"... Скобки использ...   May 11 2007, 11:33
|- - zltigo   Цитата(Ivan_Kov @ May 11 2007, 14:33) Про...   May 11 2007, 18:04
- - amw   GCC 3.4.5 gcc -o x x.c x = 14 gcc -Os -o x x.c x =...   May 11 2007, 11:33
- - zltigo   Цитата(zhevak @ May 11 2007, 14:25) как к...   May 11 2007, 11:57
- - vromanov   не страдайте фигней. Вот вам выдержка из стандарта...   May 11 2007, 12:39
|- - zltigo   Цитата(vromanov @ May 11 2007, 15:39) не ...   May 11 2007, 12:42
- - vromanov   Как любителю стандартов, вам надо было не искать о...   May 11 2007, 12:51
|- - zltigo   Цитата(vromanov @ May 11 2007, 15:51) Тут...   May 11 2007, 13:13
|- - dxp   Цитата(vromanov @ May 11 2007, 19:51) Как...   May 11 2007, 13:37
|- - Сергей Борщ   Цитата(dxp @ May 11 2007, 16:37) Очевидно...   May 11 2007, 14:22
|- - zltigo   Цитата(Сергей Борщ @ May 11 2007, 17:22) ...   May 11 2007, 14:29
- - Ivan_Kov   Я вот смотрю, и не могу никак понять, что за нужда...   May 11 2007, 15:32
- - vromanov   Удивительно, что столь очевидная вещь собрала сто...   May 11 2007, 16:08
|- - lebiga   Цитата(vromanov @ May 11 2007, 20:08) Уди...   May 11 2007, 19:57
- - defunct   Цитатаx = ++i + ++i; Это в китайских исходниках...   May 11 2007, 17:54
- - vetal   По моему все очень просто, т.к. код архитектурно з...   May 12 2007, 10:16
|- - Oldring   Цитата(vetal @ May 12 2007, 14:16) 3. x=i...   May 12 2007, 10:21
- - vetal   ЦитатаТак вот откуда взялась эта третья операция -...   May 12 2007, 10:42
|- - Oldring   Цитата(vetal @ May 12 2007, 14:42) В дере...   May 12 2007, 10:52
|- - zltigo   Цитата(vetal @ May 12 2007, 13:42) Это вп...   May 12 2007, 11:48
|- - zltigo   Цитата(Oldring @ May 12 2007, 19:06) Стан...   May 12 2007, 16:29
|- - Oldring   Цитата(zltigo @ May 12 2007, 20:29) Закон...   May 12 2007, 16:57
|- - zltigo   Цитата(Oldring @ May 12 2007, 19:57) arm-...   May 12 2007, 17:55
|- - Oldring   Цитата(zltigo @ May 12 2007, 21:55) Меня ...   May 13 2007, 08:35
|- - zltigo   Цитата(Oldring @ May 13 2007, 11:35) А с ...   May 13 2007, 06:24
|- - Oldring   Цитата(zltigo @ May 13 2007, 10:24) Посем...   May 13 2007, 06:43
|- - zltigo   Цитата(Oldring @ May 13 2007, 09:43) А во...   May 13 2007, 07:24
|- - Oldring   Цитата(zltigo @ May 13 2007, 11:24) Никак...   May 13 2007, 08:02
|- - zltigo   Цитата(Oldring @ May 13 2007, 11:02) Один...   May 13 2007, 08:11
|- - Oldring   Цитата(zltigo @ May 13 2007, 12:11) Не дв...   May 13 2007, 08:19
|- - zltigo   Цитата(Oldring @ May 13 2007, 11:19) Проб...   May 13 2007, 09:15
|- - Oldring   Цитата(zltigo @ May 13 2007, 13:15) Может...   May 13 2007, 09:27
|- - zltigo   Цитата(Oldring @ May 13 2007, 12:27) Не с...   May 13 2007, 09:38
|- - Oldring   Цитата(zltigo @ May 13 2007, 13:38) Может...   May 13 2007, 09:55
|- - zltigo   Цитата(Oldring @ May 13 2007, 12:55) В ст...   May 13 2007, 10:12
|- - Oldring   Цитата(zltigo @ May 13 2007, 14:12) Отлич...   May 13 2007, 10:26
|- - zltigo   Цитата(Oldring @ May 13 2007, 13:26) Пров...   May 13 2007, 10:37
|- - Oldring   Цитата(zltigo @ May 13 2007, 14:37) Aвтор...   May 13 2007, 11:03
|- - vromanov   Цитата(zltigo @ May 13 2007, 14:37) Ну ка...   May 13 2007, 12:03
|- - zltigo   Цитата(vromanov @ May 13 2007, 15:03) Воо...   May 13 2007, 13:15
- - Niko1a$   Посмотрите полученный ассемблерный код на своей ма...   May 12 2007, 12:42
|- - Oldring   Цитата(Niko1a$ @ May 12 2007, 16:42)...   May 12 2007, 12:46
- - vetal   nios2-elf-gcc выдает без оптимизации 13, с оптимиз...   May 12 2007, 13:09
- - vetal   ЦитатаВ обоих случаях оптимизации говорит нельзя? ...   May 12 2007, 14:57
- - singlskv   Я Вам не помешаю ? Выскажу свое ИМХО: - Компилято...   May 12 2007, 22:53
|- - zltigo   Цитата(singlskv @ May 13 2007, 01:53) - р...   May 13 2007, 06:48
|- - cebotor   Цитата(singlskv @ May 13 2007, 02:53) Я В...   May 15 2007, 06:19
|- - Oldring   Цитата(cebotor @ May 15 2007, 10:19) все ...   May 15 2007, 06:26
- - scifi   Ну вы даёте... Эту бы энергию - да в мирных целях ...   May 13 2007, 06:20
- - vromanov   А то, что значение переменной может поменяться в ...   May 14 2007, 00:07
|- - zhevak   Цитата(vromanov @ May 14 2007, 06:07) А т...   May 14 2007, 00:19
|- - vromanov   Цитата(zhevak @ May 14 2007, 04:19) не-е,...   May 14 2007, 00:22
- - amw   В пост #4 при компилляции добавляем -Wall и получа...   May 14 2007, 07:34


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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