суббота, 28 августа 2010 г.

[prog] Вот чего никогда не понимал в C-подобных языках, так это попытки найти максимум ошибок при компиляции

Когда я учился программировать на Pascal-е двадцать лет назад, там была простая и понятная схема – компиляция обламывалась на первой же ошибке. Не важно, была ли это пропущенная запятая, неизвестная переменная или недопустимое присваивание. Найдена первая ошибка и все, пока ее не исправишь, компиляция не пойдет дальше.

А вот при переходе на C, а затем и на C++, пришлось столкнуться с совсем другим поведением. C-шный компилятор пытался найти максимум ошибок и останавливался только когда их оказывалось слишком много. При этом, по моим субъективным впечатлениям, в 90% случаев только первая ошибка диагностировалась правильно. А все последующие были наведенными. Но чтобы понять это приходилось тратить время. Поэтому я уже давно при компиляции поступаю так: исправляю первую ошибку и запускаю компиляцию повторно, без попыток исправить сразу остальные найденные компилятором ошибки.

Но временами компилятор выдает такое, что поневоле приходится гадать, кто из нас двоих дурак. Вот сегодняшний пример. Пытаюсь скомпилировать файл со следующим фрагментом (это часть класса):

72    private :
73       //! Агент, от имени которого нужно выполнять логирование.
74       const so_4::rt::agent_t & m_agent,
75       //! Конфигурация cp_service.
76       const cfg_t & m_cfg,
77       //! Интерфейс доступа к БД.
78       db_iface_t & m_db;

на что компилятор (VC++ 2008 SP1) выдает мне:

.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(76) : error C2143: syntax error : missing ';' before '&'
.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(76) : error C2259: 'so_4::rt::agent_t' : cannot instantiate abstract class
        due to following members:
        'const char *so_4::rt::agent_t::so_query_type(void) const' : is abstract
        .\so_4/rt/h/agent.hpp(200) : see declaration of 'so_4::rt::agent_t::so_query_type'
        'void so_4::rt::agent_t::so_on_subscription(void)' : is abstract
        .\so_4/rt/h/agent.hpp(214) : see declaration of 'so_4::rt::agent_t::so_on_subscription'
.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(76) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(76) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(78) : error C2143: syntax error : missing ';' before '&'
.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(78) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\ig_cp_service_2/h/new_outgoing_packages_processor.hpp(78) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

В глаза почему-то бросается ошибка о невозможности создать экземпляр абстрактного класса agent_t в строке 76. Но у меня вообще нет экземпляров каких-либо классов – есть только ссылки на них!

А ошибка, в общем-то тривиальная: после атрибута m_agent я поставил запятую, а не точку с запятой (строка 74). Но диагностировать он это смог только в строке 76. И выдал более-менее понятную первую ошибку – нет точки запятой (правда я не понимаю, почему было не сказать, что нет точки с запятой перед ‘const’ или хотя бы перед ‘cfg_t’, а не перед ‘&’). Остановилась бы на этом компиляция и всех делов. А так пришлось пару минут тупить, чтобы забить на ругань компилятора об абстрактных классах и весь последующий бред :)

2 комментария:

Андрей Валяев комментирует...

Я тоже предпочитаю реагировать только на первую ошибку. Смысла нету смотреть дальше.

Да, и в случае с неопределенными типами компилятор часто начинает гнать такую пургу, ибо думает (по совместимости с си) что если встречается неизвестное слово, то перед ним наверное забыли поставить int. :)

И в результате ругается на что угодно, только не на отсутствующий тип... Любимое ругательство в этом случае на отсутствие точки с запятой...

А уж ругательства на тему шаблонов - вообще без поллитры не поймешь. Надо как-то подавать информацию в концентрированной форме.

eao197 комментирует...

Да, с шаблонами вообще мрачно. Некоторые дале используют специальные программы или скрипты чтобы приводить сообщения об ошибках компилятора к удобоваримому виду.