Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Для новичков > Во всём виноват компилятор |
Автор: Thunderbolt 10.9.2012, 14:29 | ||||
Многие программисты очень любят обвинять компилятор в различных ошибках. Поговорим немного об этом. А был ли мальчик? Когда программист говорит, что причиной ошибки является компилятор, в 99% случаев, он врёт. Когда начинается детальное изучение проблемы, то, как правило, причины такие:
Многие проходили через исправление подобных ошибок. Много читали о них. Однако это не мешает вновь и вновь обвинять в смертных грехах компилятор. Каждый раз, кажется, что вот теперь-то виноват именно он. Конечно, компилятор тоже может содержать ошибки. Но если вы не используете экзотический компилятор для микроконтроллера, то такая вероятность очень низкая. За многие годы работы с Visual C++ я только один раз видел, когда он сгенерировал некорректный ассемблерный код. Небольшая рекомендация Прежде чем винить компилятор и писать про это в коде или на форуме, проведите детальное расследование. Во-первых, так вы быстрее устраните ошибку в своём коде. Во-вторых, не будете выглядеть глупо в глазах других программистов, которые укажут на ваш ляп. Что побудило написать меня эту заметку Сегодня меня крайне позабавил фрагмент кода из проекта ffdshow. Вот он:
Глядя на комментарий, я представляю, как негодовал программист. Ах, этот несносный компилятор! В Debug-версии все переменные равны 0. В release-версии из-за неработающей оптимизации, в них мусор. Это безобразие! Плохой, плохой компилятор! Поругав компилятор, программист оставляет обвиняющий комментарий. И пишет ниже код, который по отдельности обнуляет каждый член класса. Победа мужества над силами зла. И ведь главное, этот человек останется уверенным, что встречал баг в компиляторе. И будет рассказывать, как из-за него страдал. Если кто-то не понял весь юмор ситуации, то поясню. Функция memset() не работает из-за простейшей ошибки. Третий аргумент вычисляет размер указателя, а вовсе не структуры. Корректный вызов должен выглядеть так: "memset(this, 0, sizeof(*this));". Кстати, рядом у этого программиста функция memcpy() тоже работает плохо. Уверен, что он считает разработчиков компиляторов криворукими созданиями.
Из комментариев видно, что он пытался копировать память альтернативными методами. Впрочем, потом оставил всё-таки функцию 'memcpy()'. Возможно она у него работала в 64-битной программе. Там размер указателя равен 8 байт. А именно 8 байт, он и хочет скопировать. Ошибка опять в третьем аргументе. Должно быть написано "sizeof(*this)". Вот так и рождаются легенды о глючных компиляторах и отважных программистах, которые с ними сражаются. Вывод Если что-то работает не так, ищите ошибку в своём коде. P.S. Как я наткнулся на эти ошибки? Очень просто - я использовал анализатора кода http://www.viva64.com/ru/pvs-studio/. |
Автор: boostcoder 10.9.2012, 14:43 |
жуть какая ![]() как его код вообще приняли?! |
Автор: xvr 11.9.2012, 11:17 |
Самая главная ошибка любого компилятора в том, что он компилирует то, что программист написал, а не то, о чем он думал ![]() |
Автор: borisbn 11.9.2012, 14:52 | ||
Кстати, по поводу memcpy. Недавно нарвался у себя в коде на такую ошибку: в шаблонном классе есть такой код
где m_outData - указатель на T, v - vector< T >. пока T у меня был unsigned char всё работало... На самом деле нужно было v.size() * sizeof( T ), хотя ещё лучше каким нибудь std::copy, но суть не в этом. PVS-Studio ничего в этой строке не увидел. Я ни в коем случае не утверждаю что должен был, но м.б. стОит подумать, что можно сделать в такой ситуации ? |
Автор: Dem_max 11.9.2012, 17:34 |
Да в принципе такой код memset(this, 0, sizeof(*this)); тоже страшен сам по себе. |
Автор: bsa 11.9.2012, 22:17 |
Dem_max, согласен. При использовании memset в тело класса следует добавить комментарий большими буквами: //WARNING: Use only POD types here because memset used in constructor. |
Автор: borisbn 11.9.2012, 23:38 |
Вопрос к Андрею Карпову: это - http://forum.vingrad.ru/forum/topic-356293.html - UB, ошибка компилятора или всё штатно по стандарту ? |
Автор: Thunderbolt 12.9.2012, 11:10 | ||||
Тут всё штатно. Просто у разработчиков странные и неправильные представления о числах с плавающё точкой. Нодо многое о них знать, чтобы правильно с ними работать. Вот я бы не сказал, что умею. Там масса тонкостей. Ещё немного на эту тему: http://www.viva64.com/ru/b/0074/ http://www.drdobbs.com/cpp/are-you-sure-that-your-program-works/240006889 Добавлено через 3 минуты и 47 секунд
Да, про такой паттерн PVS-Studio не знает. Записал пример в список улучшений. Спасибо. |