Описание.
При использовании наследования, шаблонов и виртуальных методов компилятор может сгенерировать неправильные таблицы виртуальных функций!
Воспроизвести на маленьком проекте, к сожалению, до сих пор не удалось. На больших проектах это вылазило уже около 5 раз. За последний месяц — два раза. Причем один и тот же код в разных проектах может скомпилироваться правильно, а может — нет.
Диагноз
Судя по всему — компилятор, при генерации методов шаблона или потомка от шаблона, иногда не видит, что метод определен как виртуальный в базовом классе. И может в производном классе оставить реализацию базового класса. Одним из глухих случаев был вариант, когда эта базовая реализация была определена как чистая виртуальная функция. А может орать, что отсутствует реализация абстрактного метода, хотя в производном классе этот метод реализован.
Еще один случай, от которого я еще не отошел — указатель элемента VT, может указывать на совершенно другую функцию!
Лечение
В каждом производном классе нужно явно указывать virtual для всех переопределяемых методов.
Так что, поклонникам этого чудовища нужно держать себя обеими руками за ... короче не расслабляться
PS. Пишу сюда, а не в средства разработки, что бы прочитало как можно больше заинтересованного народа.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Так Борланд уж сам от своего детища похоже отказывается, их новый bccx 6.0 основан на ЕДГ фронт-энде и потому очень хорош, более того. Он ... дада... он поддерживает экспорт шаблонов. Если это конечно кому-то еще интересно.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Так Борланд уж сам от своего детища похоже отказывается, их новый bccx 6.0 основан на ЕДГ фронт-энде и потому очень хорош, более того. Он ... дада... он поддерживает экспорт шаблонов. Если это конечно кому-то еще интересно.
Конечно интересно. А что это такое ЕДГ?
У кого нибуть есть реальный опыт компиляции сложных проектов на CBuilderX?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>А что это такое ЕДГ?
edg.com КД>У кого нибуть есть реальный опыт компиляции сложных проектов на CBuilderX?
у кого может и есть, а я вот просто поставил побаловаться, убедился, что экспорт и впрямь есть, порадовался и с тех пор не запускал пока
Of course, the code must be complete enough to compile and link.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
КД>>А что это такое ЕДГ? L_L> edg.com КД>>У кого нибуть есть реальный опыт компиляции сложных проектов на CBuilderX? L_L>у кого может и есть, а я вот просто поставил побаловаться, убедился, что экспорт и впрямь есть, порадовался и с тех пор не запускал пока
А как его оттуда достать? Он платный?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Lorenzo_LAMAS, Вы писали:
КД>>А что это такое ЕДГ? L_L> edg.com КД>>У кого нибуть есть реальный опыт компиляции сложных проектов на CBuilderX? L_L>у кого может и есть, а я вот просто поставил побаловаться, убедился, что экспорт и впрямь есть, порадовался и с тех пор не запускал пока
Вопрос в догонку: правда ли что ему нужен оочень мощный комп что бы нормально работать?
Да и вообще как у него со скоростью компиляции?
Здравствуйте, Lorenzo_LAMAS, Вы писали:
LVV>>А как его оттуда достать? Он платный?
L_L>На www.borland.com позволяют скачать CBuilderX и Borland C++ Technical Preview — бесплатно.
Не, я про edg спрашивал.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
LVV>Не, я про edg спрашивал.
Едг не занимается созданием и продажей своего компилятора обычным пользователям. Подробности на edg.com
вроде как едг преподам — профессорам и т.д., занимающимся научной деятельностью может предоставить исходники — попробуйте.
Of course, the code must be complete enough to compile and link.
Здравствуйте, LaptevVV, Вы писали:
LVV>Не, я про edg спрашивал.
Несколько десятков-сотен тысяч долларов — в зависимости от целей использования — и он ваш!
А если серьезно, они в принципе могут давать код учебным заведениям для "исследовательских нужд", но это решается естественно, индивидуально. Сомневаюсь, что в нашу пиратскую страну дадут.
Все, что здесь сказано, может и будет использоваться против меня...
Здравствуйте, Коваленко Дмитрий, Вы писали: КД>При использовании наследования, шаблонов и виртуальных методов компилятор может сгенерировать неправильные таблицы виртуальных функций! КД>....Одним из глухих случаев был вариант, когда эта базовая реализация была определена как чистая виртуальная функция.
Хотелось бы добавить пример в тему.
template<class T>
class base
{
public:
virtual f1()=0;
};
template<class T>
class foo : public base<T>
{
};
class bar
{
public:
foo<int> m_foo;
};
int main()
{
bar b;
b.m_foo.f1();
return 0;
}
Все компилится и получаем, есессно, pure virtual function called.
P.S. в vc7.1 все нормально.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Так Борланд уж сам от своего детища похоже отказывается, их новый bccx 6.0 основан на ЕДГ фронт-энде и потому очень хорош, более того. Он ... дада... он поддерживает экспорт шаблонов. Если это конечно кому-то еще интересно.
Здравствуйте, srd, Вы писали:
srd>Объясните неграмотному, что такое front-end?
Front-end — часть компилятора, выполняющего лексический и синтаксический анализ исходной программы; осуществляющая оптимизацию, зависимую от исходного языка и транслирующая программу в некоторый промежуточный код. В дальнейшем этот промежуточный код оптимизируется и транслируется на уровень машинных команд back-end -ом.
Подобный подход позволяет четко разделить фазы трансляции, зависимые от исходного языка, от фаз трансляции, зависимых от конечной системы; использовать один кодогенератор (back-end) с одним и тем же оптимизатором для разных исходных языков, подключая разные front-end -ы, и наоборот, легко переносить компилятор на другие платформы, меняя только back-end.
На таком подходе основан, например, GCC, который имеет front-end -ы для C++, Java, Ada и др.; а также например .Net, в котором front-end -ы для C++, C#, Basic проводят компиляцию в общий для всех промежуточный код.
Упомянутый EDG front-end для C++ в настоящее время более всего соответствует стандарту C++. На нем основаны такие компиляторы как Intel C++ compiler, Comeau и др. Также Edison Design Group разработала front-end — ы для Java, Fortran.
Все, что здесь сказано, может и будет использоваться против меня...
Здравствуйте, barrett, Вы писали:
КД>>....Одним из глухих случаев был вариант, когда эта базовая реализация была определена как чистая виртуальная функция.
B>Хотелось бы добавить пример в тему.
B>Все компилится и получаем, есессно, pure virtual function called. B>P.S. в vc7.1 все нормально.
Я тут еще одну штуку в BCB5 обнаружил
Могут не вызываться inline конструкторы шаблонов
Первый раз это проявилось на том, что программа падала на вызове виртуальной функции добавленной в этом шаблоне. Тогда я не понял что к чему. А сегодня assert выловил неинициализированный член этого класса. Простите что выругался . Начал копаться — не вызывается конструктор. Думаю, первый раз проблема был тоже с этой ошибкой связана.
Вынес реализацию из объявления класса и убрал inline — конструктор начал вызываться.
Самое забавное, что большинство критически важных программ работает — начальное этой переменной == false, а память под объекты производных классов выделяется с инициализацией нулями
Я тут еще раз поэксперементировал с твоим примером — явно определенные не inline конструкторы ему не помогают
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Диагноз КД>... А может орать, что отсутствует реализация абстрактного метода, хотя в производном классе этот метод реализован.
Комбинация множественного наследования, шаблонов и абстрактных методов приводит к полному ступору этого компилятора. Причем крыша рвется именно от последней вещи — абстрактных методов. Я так и не смог понять в каком порядке он инстанцирует классы/методы, что бы подобрать секретный код к успешной компиляции Пришлось отказаться от абстрактных методов, реализовав заглушки.
И как при таких раскладах можно писать по-настоящему интересные программы ?
КД>PS. Пишу сюда, а не в средства разработки, что бы прочитало как можно больше заинтересованного народа.
Ага. Привет западному полушарию
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
[]
КД>Так что, поклонникам этого чудовища нужно держать себя обеими руками за ... короче не расслабляться
Ну, про чудовище это вы верно заметили. А как вы думали, накохер всякие DYNAMIC, PACKAGE и пр. муйня в дебилдере была в свое время введена? DYNAMIC, если мне не изменяет склероз — это define к virtual, причем его во всех местах рекомендуют использовать тогда, когда дело как раз доходит до наследования от классов с виртуальными методами
Если дебилдер версии 1.0 был еще ничего, то в дальнейшем, конечно, Правда, я по долгу службы с ним повязан, но давно уже приучил себя к одной простой вещи — не мудрствовать. Т.е. писать железно, чтобы уж точно все работало
З.Ы. VC++ 6.0 по мне так гораздо приятнее — пишешь функциональный модуль и наслаждаешься... Вот еще бы VS.NET в плане визуальности к уровню дельфей подтянуть — и все, можно сказать, что дебилдер меня потеряет
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Пришлось отказаться от абстрактных методов, реализовав заглушки.
При должном окапывании у меня абстрактные методы работают Правда, я их пользую только тогда, когда ни один из базовых классов и близко не относится к VCL. Может, в этом дело? Хотя у меня все достаточно просто. Как пример — вот такая поделка вполне работает:
Т.е. есть классы-наследники от TSearchInterface и все как-то живет... Правда, стоит заметить, что в приведенном примере TSearchInterface — не чисто абстрактный класс. Может, в этом все дело? Или может я что неправильно делаю?
Здравствуйте, Flamer, Вы писали:
F>Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>>Пришлось отказаться от абстрактных методов, реализовав заглушки.
F>При должном окапывании у меня абстрактные методы работают Правда, я их пользую только тогда, когда ни один из базовых классов и близко не относится к VCL. Может, в этом дело?
Если бы тут был виноват VCL . Я мучал чистый C++.
У меня базовые классы с абстракными методами (они тоже не являются чистыми абстрактными методами) оформленны в виде шаблонов. От них (их было две штуки) порождается другой шаблонный класс. Потом сделан еще один шаблон (третий уровень наследования).
Во третий уровнь (где у всех абстрактные методы уже реализованы) — все равно не может использоваться для создания объктов — компилятор ругается на не реализованные методы.
Ладно. Я и так, из-за бурной ночи? проспал до 10 утра — пора на работу. VBScript — форева
Если интересно — я могу тебе прислать исходники для экспериментов.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Flamer, Вы писали:
F>Если дебилдер версии 1.0 был еще ничего,
Ага, я помню свои кривые руки, BCB1 и NT4 WS без патчей.
Сначала при компиляции кода с goto с выходом из try{}catch падал компилятор, в второй раз падал NT
F>З.Ы. VC++ 6.0 по мне так гораздо приятнее
Спаси Господи от программирования на VC6
Он наверное стабильнее BCB, но тупой, в плане C++, до безобразия.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Ага, я помню свои кривые руки, BCB1 и NT4 WS без патчей. КД>Сначала при компиляции кода с goto с выходом из try{}catch падал компилятор, в второй раз падал NT
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Спаси Господи от программирования на VC6 КД>Он наверное стабильнее BCB, но тупой, в плане C++, до безобразия.
Уж лучше VC6 чем сидеть и бояться рванет или не рванет...
... << RSDN@Home 1.1.4 rev. 142 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, barrett, Вы писали:
B>P.S. в vc7.1 все нормально.
Всё нормально — в смысле, компилятор выдаёт ошибку "невозможно создать объект абстрактного класса"?
Здравствуйте, Коваленко Дмитрий, Вы писали:
F>>З.Ы. VC++ 6.0 по мне так гораздо приятнее КД>Спаси Господи от программирования на VC6 КД>Он наверное стабильнее BCB, но тупой, в плане C++, до безобразия.
Он тупой, но предсказуемый. В нём есть ряд приколов разной степени злобности — но известны и способы их объезда.
А по части тупизны... Старый gcc 2.7.2 горааааздо тупее.