Возникла следующая проблема,заключающаяся в непредсказуемом поведении компилятора VC++.
Есть три класса:
class Father
{
// ....
};
class Mother
{
//......virtual void foo() = 0;
//......
};
class Daughter : public Father, public Mother
{
//.........void foo() override;
};
void Daughter::foo()
{
//....
}
При попытке вызвать Daughter::foo все рушится. Как следует из просмотра asm-листинга, в vftable там, где по идее должен был бы находится адрес Daughter::foo, находится непонятно что. Выглядит вызов следующим образом:
Выглядит все вроде бы правильно, но при просмотре в дебагере видно, что в eax оказывается вовсе не адрес Daughter::foo. С точки зрения синтаксиса вроде бы тоже все правильно. Что это, глюк компилятора?
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re: Абстрактный класс и множественное наследование
G>При попытке вызвать Daughter::foo все рушится.
Не понял. Ты метод как метод класса вызываешь? Виртуальный?
Где объект или указатель на объект, от которого метод должен вызывать?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Абстрактный класс и множественное наследование
Здравствуйте, LaptevVV, Вы писали:
LVV>Не понял. Ты метод как метод класса вызываешь? Виртуальный?
Как виртуальный. Если конкретно вызывать Daughter::foo, то все конечно замечательно. LVV>Где объект или указатель на объект, от которого метод должен вызывать?
Это не принципиально, поэтому я опустил эти подробности для краткости изложения. И к тому же из ассемблера это понятно.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Здравствуйте, Gregory, Вы писали:
G>При попытке вызвать Daughter::foo все рушится. Как следует из просмотра asm-листинга, в vftable там, где по идее должен был бы находится адрес Daughter::foo, находится непонятно что. Выглядит вызов следующим образом:
G>
Вы что-то не договариваете. Вы вы зываете foo из метода 4-го класса кторый наследуется от Дочери.
Видимо проблема в преобразовании типов, а не в приведённом коде.
У меня генерит примерно такой же код:
Здравствуйте, kov_serg, Вы писали:
_>Вы что-то не договариваете. Вы вы зываете foo из метода 4-го класса кторый наследуется от Дочери. _>Видимо проблема в преобразовании типов, а не в приведённом коде.
Вовсе нет. На самом деле приведенный asm — это вызов foo из другого метода дочки.
Если вызвать так:
Daughter d;
d.foo();
результат будет тот же.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re: Абстрактный класс и множественное наследование
Здравствуйте, Gregory, Вы писали:
G>Возникла следующая проблема,заключающаяся в непредсказуемом поведении компилятора VC++. G>Есть три класса: G>При попытке вызвать Daughter::foo все рушится. Как следует из просмотра asm-листинга, в vftable там, где по идее должен был бы находится адрес Daughter::foo, находится непонятно что. Выглядит вызов следующим образом: G>Выглядит все вроде бы правильно, но при просмотре в дебагере видно, что в eax оказывается вовсе не адрес Daughter::foo. С точки зрения синтаксиса вроде бы тоже все правильно. Что это, глюк компилятора?
Я попробовал доработать исходный пример и запустил его на Visual Studio 2015 и на GCC-6.3, никаких проблем не обнаружил:
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Gregory, Вы писали:
R>Я попробовал доработать исходный пример и запустил его на Visual Studio 2015 и на GCC-6.3, никаких проблем не обнаружил:
R>https://ideone.com/TbjBEN.
R>Поэтому для начала хотелось бы понимать, о какой версии студии идет речь, а так же увидеть минимальный рабочий пример, воспроизводящий проблему.
VS 2012
В этом упрощенном виде пример действительно работает. Конкретный код сюда тащить не хочется. Он большой и навороченный. Я попробую смоделировать ситуацию в более простом виде и отпишусь.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re[2]: Абстрактный класс и множественное наследование
Здравствуйте, Gregory, Вы писали:
G>VS 2012 G>В этом упрощенном виде пример действительно работает. Конкретный код сюда тащить не хочется. Он большой и навороченный. Я попробую смоделировать ситуацию в более простом виде и отпишусь.
Признаться, примерно такого ответа я и ожидал
По моему опыту, когда что-то падает, но не воспроизводится на простом примере, проблема обычно кроется совсем не там, где кажется на первый взгляд. Скорее всего, какое-то UB в программе — неинициализированные переменные, заезды по памяти, неправомерные static- и reintepret_cast-ы, пр., и др., и т.п.
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: Абстрактный класс и множественное наследование
Здравствуйте, rg45, Вы писали:
R>Признаться, примерно такого ответа я и ожидал
R>По моему опыту, когда что-то падает, но не воспроизводится на простом примере, проблема обычно кроется совсем не там, где кажется на первый взгляд. Скорее всего, какое-то UB в программе — неинициализированные переменные, заезды по памяти, неправомерные static- и reintepret_cast-ы, пр., и др., и т.п.
Ну да, вы совершенно правы. Я проглядел, что в результате множественного наследования случилась diamond problem. А когда стал упрощать код, чтобы локализовать ошибку, сразу ее заметил.
Не дай своим глазам увидеть, а ушам услышать то, что ты не сможешь объяснить.
Абрахам ван Хелсинг
Re[3]: Абстрактный класс и множественное наследование
G>Почему ты так уверен? Никогда с глюками компилятора не сталкивался, особенно при оптимизации?
Глюки компилятора при оптимизации — это баги (неопределенное поведение) в твоей программе. Чем скорее ты это поймешь, ием лучше для тебя. У компиляторов, конечно, бывают баги, но они так не проявляются.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: Абстрактный класс и множественное наследование
Здравствуйте, Gregory, Вы писали:
G>Ну да, вы совершенно правы. Я проглядел, что в результате множественного наследования случилась diamond problem. А когда стал упрощать код, чтобы локализовать ошибку, сразу ее заметил.
Ну и хорошо, что всё работает!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском