![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Thunderbolt |
|
||||||||||||||||||||
![]() DevRel ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 7.11.2007 Где: Тула Репутация: 10 Всего: 16 |
Cfront это компилятор для С++, существующий примерно с 1983 года и разработанный Бьёрном Страуструпом. В то время он был известен как "C с классами". Cfront имел полноценный парсер, таблицы символов, строил дерево для каждого класса, функции и т.д. Cfront был основан на CPre. Cfront определял развитие языка приблизительно до 1990г. Многие неясные моменты, имеющие место в С++, связаны с ограничениями реализации Cfront. Причина в том, что Cfront осуществлял трансляцию с C++ в C. Одним словом, Cfront - это священный артефакт для любого C++ программиста. И я просто не мог пройти мимо, не проверив этот проект.
Введение На идею проверить Cfront меня натолкнула заметка, приуроченная к 30-летию первой Release версии этого компилятора: "30 YEARS OF C++". Мы связались с Бьёрном Страуструпом, чтобы заполучить исходные коды Cfront. Я почему-то думал, что достать их будет целая история. Оказалось, всё просто. Эти исходники лежат в открытом доступе по адресу http://www.softwarepreservation.org/projects/c_plus_plus/ и доступны всем желающим. Для проверки была выбрана первая коммерческая версия Cfront, выпущенную в октябре 1985 года. Ведь именно ей исполнилось 30 лет. Бьёрн предупредил нас, что с проверкой может оказаться не всё так просто: Please remember this is *very* old software designed to run on a 1MB 1MHz machine and also used on original PCs (640KB). It was also done by one person (me) as only part of my full time job. И действительно. Вот так просто взять и проверить проект оказалось невозможным. Например, в те времена для отделения имени класса от имени функции использовалось не четыре точки (: ![]()
Анализатор PVS-Studio был к этому не готов. Пришлось подключить коллегу студента, который вручную прошелся по исходникам и поправил их. Это помогло, хотя и не до конца. Все равно во многих местах PVS-Studio выпучивает глаза и отказывается анализировать. Тем не менее, кое как нам удалось проверить проект. Сразу скажу, что я не нашел чего-то грандиозного. Не нашлось серьезных багов, думаю по 3 причинам:
"Это все слова. Покажи мне код." © Линус Торвальдс Однако хватит слов. Наши читатели собрались здесь, чтобы увидеть хоть одну ошибку самого Страуструпа. Давайте смотреть код. Первый фрагмент
Предупреждение PVS-Studio: V595 The 'cl' pointer was utilized before it was verified against nullptr. Check lines: 927, 928. expr.c 927 Указатель 'cl' может быть равен NULL. Об этом свидетельствует проверка if (cl == 0). Беда в том, что ещё до этой проверки этот указатель разыменовывается. Это происходит в макросе PERM. Т.е. если раскрыть макрос, то получаем:
Второй фрагмент То же самое. Разменивали указатель, и только потом его проверили:
Предупреждение PVS-Studio: V595 The 'b' pointer was utilized before it was verified against nullptr. Check lines: 608, 615. norm.c 608 Третий фрагмент
Предупреждение PVS-Studio: V563 It is possible that this 'else' branch must apply to the previous 'if' statement. error.c 164 Не знаю, есть здесь ошибка или нет, но код оформлен неправильно. 'else' относится к ближайшему 'if'. Поэтому код работает не так, как выглядит. Если отформатировать его правильно, то получится:
Четвертый фрагмент
Предупреждение PVS-Studio: V576 Incorrect format. A different number of actual arguments is expected while calling 'fprintf' function. Expected: 3. Present: 4. generic.c 8 Обратите внимание на format specifiers: "%s". Будет распечатана строка. А вот переменная 'n' осталась не при деле. Прочее К сожалению (или к счастью), больше ничего похожего на настоящие ошибки я показать не могу. Анализатор выдал ряд предупреждений на код, который хотя и заслуживает внимание, но не является опасным. Например, анализатору не нравятся имена следующих глобальных переменных:
Предупреждение PVS-Studio: V707 Giving short names to global variables is considered to be bad practice. It is suggested to rename 'Nn' variable. cfront.h 50 Или, например, для распечатки значений указателей функцией fprintf() использует спецификатор "%i". В современной версии языка для этого служит "%p". Но как я понимаю, 30 лет назад никакого "%p" ещё не было, и код совершенно корректен. Интересные наблюдения Указатель this Обратил внимание, что раньше с 'this' работали на порядок более смело и грубо. Пара примеров на эту тему:
Как видите, в те времена не считалось чем-то запретным, взять и поменять значение 'this'. Сейчас запрещается не только менять указатель, но и даже потеряли смысл сравнения this с nullptr. This is the place for paranoia Как говорится, ни в чем нельзя быть уверенным. Понравился вот такой фрагмент кода, на который я натолкнулся:
Комментарий Бьёрна Страуструпа
Выводы Значение Cfront сложно переоценить. Он оказал влияние на развитие целой отрасли программирования и подарил миру вечно живой и развивающийся язык C++. Выражаю Бьёрну благодарность за всю проделанную им работу в создании С++. Спасибо. Мне в свою очередь было приятно хотя бы "постоять рядом" с Cfront. Спасибо всем читателям, и хочу пожелать поменьше багов. --------------------
Карпов Андрей, DevRel в PVS-Studio. |
||||||||||||||||||||
|
|||||||||||||||||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |