Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> странное поведение компилятора, оптимизация в Visual C++ 7.1 
V
    Опции темы
likehood
Дата 3.4.2007, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Сегодня столкнулся со странным поведением компилтора (Visual C++ 7.1) на таком простом коде:
Код

#include <iostream>

int f1() {
    static as = 1;
    return (++as)+1;
}

int main() {
    std::cout << f1()+f1() << "\n";
    return 0;
}


Вывод этой программы различный для Debug и Release версий: в отладочной версии результат вполне ожидаемый - 7, в то время как в релизе - 8. Я так и не нашел какие настройки компилятора влияют на этот результат, возможно это ошибка компилятора.

Вот и интересно, может кто-то сталкивался с такой проблемой.
К сожалению, у меня нет других компиляторов под рукой для проверки, особенно интересно было бы проверить в VS 2005.

Какие будут идеи?
PM MAIL   Вверх
nickless
Дата 3.4.2007, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(likehood @  3.4.2007,  18:23 Найти цитируемый пост)
Какие будут идеи?

Не делай так.
Результат выражения, где переменная одновременно читается и изменяется несколько раз неопределён. см. Страуструпа


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Daevaorn
Дата 3.4.2007, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Да. Чистый UB. Компилятор прав.
PM MAIL WWW   Вверх
archimed7592
Дата 3.4.2007, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Daevaorn, гхм...а где здесь UB? вызов ф-ции подразумевает её исполнение от начала и до конца... т. о. как не крути должно быть 7...

Добавлено через 4 минуты и 43 секунды
и к слову, по стандарту нужно писать static int as = 1;
и, что mingw-3.4.2, что vs-8.0sp1, что в debug, что в release выдаёт 7...скорее это баг старой студии (она далека от стандарта...)


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
likehood
Дата 3.4.2007, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(nickless @  3.4.2007,  20:34 Найти цитируемый пост)
Результат выражения, где переменная одновременно читается и изменяется несколько раз неопределён.

Что-то я в упор не вижу в каком выражении происходит то, что вы описали. Можно поподробнее?

Добавлено через 1 минуту и 9 секунд
Цитата(archimed7592 @  3.4.2007,  20:55 Найти цитируемый пост)
и к слову, по стандарту нужно писать static int as = 1;

Торопился просто, не заметил, а компилятор не подправил.

Добавлено через 2 минуты и 10 секунд
Цитата(archimed7592 @  3.4.2007,  20:55 Найти цитируемый пост)
скорее это баг старой студии (она далека от стандарта...)

Думаю, далекость от стандарта здесь не причем. Здесь банальная логика нарушается.
PM MAIL   Вверх
archimed7592
Дата 3.4.2007, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(likehood @  3.4.2007,  20:00 Найти цитируемый пост)
Здесь банальная логика нарушается. 
просто при оптимизации компилятор разворачивает это в inline, а о том, что это вызов ф-ции забывает...получается
Код
#include <iostream>

int main() {
    int as = 1;
    std::cout << ((++as)+1)+((++as)+1) << "\n";
    return 0;
}
а здесь воистину UB, но это головная боль компилятора, чтобы обрабатывать такое...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
nickless
Дата 3.4.2007, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Цитата(likehood @  3.4.2007,  19:00 Найти цитируемый пост)
Что-то я в упор не вижу в каком выражении происходит то, что вы описали

Я думаю, что вот тут 
Код

std::cout << f1()+f1() << "\n";
 вызов f1 в релизе инлайнится, и получается (++as)+1 + (++as)+1

Может это и баг студии, но ИМХО всё же лучше быть поосторожнее


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
likehood
Дата 3.4.2007, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(nickless @  3.4.2007,  21:14 Найти цитируемый пост)
вызов f1 в релизе инлайнится, и получается (++as)+1 + (++as)+1

Ну это уже проблемы компилятора как он заинлайнит фунцию. Замена простой функции на встроенную не должна менять логику работы программы.
Цитата(nickless @  3.4.2007,  21:14 Найти цитируемый пост)
Может это и баг студии, но ИМХО всё же лучше быть поосторожнее

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

Что ж, похоже это действительно ошибка студии. Всем спасибо за помощь. Вопрос решен.
PM MAIL   Вверх
IvanoffAndrey
Дата 3.4.2007, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 8.7.2006
Где: СГАУ

Репутация: нет
Всего: 2



Насколько мне память не изменяет return (++as)+1; не гарантирует что  (++as)+1 - вычислится, по стандарту оператор return (). Т.е. здесь можно написать return( (++as)+1) - тогда вроде должно работать. Аналогичная ситуация с return(0)-ибо правильнее.
--------------------
Размерность пространства есть число Pi и в каждой точке вселенной оно стремиться к этому числу.
PM MAIL   Вверх
Daevaorn
Дата 3.4.2007, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(IvanoffAndrey @  3.4.2007,  21:33 Найти цитируемый пост)
Насколько мне память не изменяет

изменяет;)
PM MAIL WWW   Вверх
threef
Дата 4.4.2007, 01:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 9
Всего: 10



Daevaorn
Цитата

Цитата(IvanoffAndrey @  3.4.2007,  21:33 )
Насколько мне память не изменяет

изменяет;) 

согласный.
Код

    mov    eax, DWORD PTR ?as@?1??f1@@YAHXZ@4HA ;вот и inline 
    add    eax, 2                                                                ; а это "крутейшая" оптимизация - два ++
    mov    DWORD PTR ?as@?1??f1@@YAHXZ@4HA, eax  
    push    OFFSET FLAT:??_C@_01EEMJAFIK@?6?$AA@
    lea    eax, DWORD PTR [eax+eax+2]                        
    push    eax


кстати, у меня и в дебуге тоже 8 ( оптимизация, виш ли)
PM MAIL   Вверх
IvanoffAndrey
Дата 4.4.2007, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 8.7.2006
Где: СГАУ

Репутация: нет
Всего: 2



Цитата

Цитата(IvanoffAndrey @  3.4.2007,  21:33 Найти цитируемый пост)
Насколько мне память не изменяет

изменяет;) 

Не буду тебя переубеждать, однако так всегда пишут, во всяком случае у меня в институте.
--------------------
Размерность пространства есть число Pi и в каждой точке вселенной оно стремиться к этому числу.
PM MAIL   Вверх
Daevaorn
Дата 4.4.2007, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(IvanoffAndrey @  4.4.2007,  19:38 Найти цитируемый пост)
Не буду тебя переубеждать, однако так всегда пишут, во всяком случае у меня в институте. 

Эх, чего только не пишут в интститутах.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1078 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.