О важности понимания происходящего

Submitted by 0xd34df00d on Sun, 10/19/2008 - 22:07

Препроцессор и WinAPI — зло. Потому что в последнем есть функция AddJob, которая при помощи первого подменяется AddJobA. А так как в моем коде тоже была функция-член класса TorrentPlugin, называется AddJob, то она тоже превращалась в AddJobA, отсюда были очень странные ошибки — если в файле с реализацией инклюд файла с определением положить в конец всех инклюдов, то линкер ругался, что undefined reference to function AddJob в файле, сгенеренном moc'ом. Если же инклюд поставить в начало файла реализации, то компилятор ругался, что нет функции AddJobA в классе TorrentPlugin. Естественно, если обозвать AddJob как AddJobполнаяхерня, то все прекрасно видится и ничего не подставляется.

Да, довольно глупая и очевидная, но забавная ошибка. Вот. +1 в копилку опыта.

Под катом — как лже-френд insooo помог мне разобраться в проблеме.

<0xd34df00d> На строчку int TorrentPlugin::AddJob (const QString& name, LeechCraft::TaskParameters parameters)
<0xd34df00d> он ругается, что нет функции AddJobA в классе TorrentPlugin.
<0xd34df00d> Если я напишу AddJobхерня, то он ругнется на AddJobхерня.
<0xd34df00d> Но если пишу AddJob, то ругается на AddJobA.
<0xd34df00d> Пиздец какой-то.
<0xd34df00d> Не знаешь, в чем проблема может быть?
<warfish> хы
<0xd34df00d> gcc 4.3.2, венды.
<warfish> тупо но попробуй селект-олл, копировать и вставить в свежо созданный документ)
<0xd34df00d> Уже пробовал.
<warfish> а ф-ции AddJobA у тебя вообще нету?
<warfish> у тебя только AddJob?
<0xd34df00d> Вообще. Нигде.
<0xd34df00d> Ага.
<warfish> ругается линкер или компилятор?
<0xd34df00d> Компилятор.
<0xd34df00d> Если я #include "torrentplugin.h" (файл с определением класса) помещу не в начале всех инклюдов, а в конце, то будет ругаться линкер, что undefined reference.
<warfish> а если ф-цию определить прямо внутри объявления?
<0xd34df00d> Попробую, компилится ща.
<0xd34df00d> Долго же оно компилится...
<0xd34df00d> Уйти что ли с экспериментальной ветки... Обратно на 3.х.
<0xd34df00d> Ща компилится.
<warfish> ну выглядит конечно дико
<0xd34df00d> Бред какой-то.
<0xd34df00d> Интересно, чего оно так.
<warfish> а ты попробуй отпрероцессить этот сурс
<warfish> и посмотреть что будет
<warfish> собралось с инлайном метода?
<0xd34df00d> Да, собралось с инлайном... Почти что.
<warfish> у меня есть единственное объяснение
<warfish> где-то в инклюдах был макрос
<warfish> который меняет имя твоего метода
<warfish> ф-ции со всякими A это обычно виндовые макросы
<0xd34df00d> А почему тогда после того, как я запрятал определение функции в хедер, но не убрал из .cpp, то ругалось, что redefenition?
<0xd34df00d> Не должно по идее было.
<warfish> а вот хз
<warfish> в смысле понятно почему ругается
<warfish> потому что редифинишен
<warfish> но по идее как раз не должен ругаться
<0xd34df00d> Ну да, вот-вот.
<warfish> но это объясняет оба варианта ошибки в прошлый раз
<0xd34df00d> ?
<warfish> попробуй отпрепроцессить и посмотреть как метод обховется в цпп файле
<0xd34df00d> Блин... Ща попробую.
<warfish> у гцц там есть ключик
<warfish> просто натрави его на этот сурс с препроцессором
<warfish> если дело в макросе, то ты увидишь имя метода после препроцессора в резалте
<warfish> под виндой вот часто бывают такие макросы типа GetResource, которые выворачиваются в GetResourceA
<warfish> но обычно они все-таки инлайн ф-ции а не макросы
<0xd34df00d> Слушай.
<0xd34df00d> Макрос в хедере все объясняет.
<0xd34df00d> Потому что сначала линкер ругался на undefined reference to TorrentPlugin::AddJob, который упомянут в файле, созданом Qt'шным moc'ом.
<0xd34df00d> А в этом файле секция хедеров вообще голая.
<warfish> вот я и говорю
<0xd34df00d> Очевидно, там макроса не было.
<0xd34df00d> Просто сделаю #undef AddJob после всех инклюдов тогда
<warfish> я тебе это говорил, когда писал про то что это объясняет оба проявления ошибки)
<warfish> ну ты сделай ифдеф\андеф
<warfish> в хидере своего класса
<0xd34df00d> Так и сделаю.
<warfish> и скажи чо будет
<warfish> а то заинтриговал)
<0xd34df00d> Щас тогда глобальный svn revert, а то намудрил уже.
<0xd34df00d> Надо бы вообще грепнуться по дереву, посмотреть, что именно дефайнит AddJob.
<0xd34df00d> Потому что с #ifdef/#undef все собралось.