![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Thunderbolt |
|
||||
![]() DevRel ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 7.11.2007 Где: Тула Репутация: 6 Всего: 16 |
Многие программисты очень любят обвинять компилятор в различных ошибках. Поговорим немного об этом.
А был ли мальчик? Когда программист говорит, что причиной ошибки является компилятор, в 99% случаев, он врёт. Когда начинается детальное изучение проблемы, то, как правило, причины такие:
Многие проходили через исправление подобных ошибок. Много читали о них. Однако это не мешает вновь и вновь обвинять в смертных грехах компилятор. Каждый раз, кажется, что вот теперь-то виноват именно он. Конечно, компилятор тоже может содержать ошибки. Но если вы не используете экзотический компилятор для микроконтроллера, то такая вероятность очень низкая. За многие годы работы с Visual C++ я только один раз видел, когда он сгенерировал некорректный ассемблерный код. Небольшая рекомендация Прежде чем винить компилятор и писать про это в коде или на форуме, проведите детальное расследование. Во-первых, так вы быстрее устраните ошибку в своём коде. Во-вторых, не будете выглядеть глупо в глазах других программистов, которые укажут на ваш ляп. Что побудило написать меня эту заметку Сегодня меня крайне позабавил фрагмент кода из проекта ffdshow. Вот он:
Глядя на комментарий, я представляю, как негодовал программист. Ах, этот несносный компилятор! В Debug-версии все переменные равны 0. В release-версии из-за неработающей оптимизации, в них мусор. Это безобразие! Плохой, плохой компилятор! Поругав компилятор, программист оставляет обвиняющий комментарий. И пишет ниже код, который по отдельности обнуляет каждый член класса. Победа мужества над силами зла. И ведь главное, этот человек останется уверенным, что встречал баг в компиляторе. И будет рассказывать, как из-за него страдал. Если кто-то не понял весь юмор ситуации, то поясню. Функция memset() не работает из-за простейшей ошибки. Третий аргумент вычисляет размер указателя, а вовсе не структуры. Корректный вызов должен выглядеть так: "memset(this, 0, sizeof(*this));". Кстати, рядом у этого программиста функция memcpy() тоже работает плохо. Уверен, что он считает разработчиков компиляторов криворукими созданиями.
Из комментариев видно, что он пытался копировать память альтернативными методами. Впрочем, потом оставил всё-таки функцию 'memcpy()'. Возможно она у него работала в 64-битной программе. Там размер указателя равен 8 байт. А именно 8 байт, он и хочет скопировать. Ошибка опять в третьем аргументе. Должно быть написано "sizeof(*this)". Вот так и рождаются легенды о глючных компиляторах и отважных программистах, которые с ними сражаются. Вывод Если что-то работает не так, ищите ошибку в своём коде. P.S. Как я наткнулся на эти ошибки? Очень просто - я использовал анализатора кода PVS-Studio. --------------------
Карпов Андрей, DevRel в PVS-Studio. |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
жуть какая
![]() как его код вообще приняли?! |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Самая главная ошибка любого компилятора в том, что он компилирует то, что программист написал, а не то, о чем он думал
![]() |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
Кстати, по поводу memcpy. Недавно нарвался у себя в коде на такую ошибку: в шаблонном классе есть такой код
где m_outData - указатель на T, v - vector< T >. пока T у меня был unsigned char всё работало... На самом деле нужно было v.size() * sizeof( T ), хотя ещё лучше каким нибудь std::copy, но суть не в этом. PVS-Studio ничего в этой строке не увидел. Я ни в коем случае не утверждаю что должен был, но м.б. стОит подумать, что можно сделать в такой ситуации ? -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 4 Всего: 39 |
Да в принципе такой код memset(this, 0, sizeof(*this)); тоже страшен сам по себе.
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Dem_max, согласен. При использовании memset в тело класса следует добавить комментарий большими буквами: //WARNING: Use only POD types here because memset used in constructor.
|
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
Вопрос к Андрею Карпову: это - http://forum.vingrad.ru/forum/topic-356293.html - UB, ошибка компилятора или всё штатно по стандарту ?
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
||||
|
||||
Thunderbolt |
|
||||
![]() DevRel ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 7.11.2007 Где: Тула Репутация: 6 Всего: 16 |
Тут всё штатно. Просто у разработчиков странные и неправильные представления о числах с плавающё точкой. Нодо многое о них знать, чтобы правильно с ними работать. Вот я бы не сказал, что умею. Там масса тонкостей. Ещё немного на эту тему: http://www.viva64.com/ru/b/0074/ http://www.drdobbs.com/cpp/are-you-sure-th...works/240006889 Добавлено через 3 минуты и 47 секунд
Да, про такой паттерн PVS-Studio не знает. Записал пример в список улучшений. Спасибо. --------------------
Карпов Андрей, DevRel в PVS-Studio. |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |