Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Превратности VTBL (число прочтений - 5363 )
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Превратности VTBL
21. Марта 2007 :: 22:37
Печать  
Тема, видать, совсем для энтузиастов

Я всегда полагал, что VTBL выстраивается четко в соответствии с порядком объявления функций-членов.
И для перечисления типа

virtual A();
virtual B();
virtual C();

порядок VTBL всегда будет A, B, C.

Так оно и есть, если бы не перегруженные функции, для которых порядок построения VTBL в точности противоположен их объявлению в классе.
Кроме того, перегруженные функции [в VTBL] всегда расположены рядом, независимо от порядка объявления.

К примеру, для класса

class CTest
{
public:
     virtual A() { Msg("Test"); };
     virtual void Test(LPCSTR sz) { Msg ("Test"); };
     virtual B() { Msg("Test"); };
     virtual void Test() { Msg ("Test"); };
     virtual void Test(int i) { Msg ("Test"); };
     virtual C() { Msg("Test"); };
};


Порядок VTBL будет (адреса, конечно)

     virtual A() { Msg("Test"); };
     virtual void Test(int i) { Msg ("Test"); };
     virtual void Test() { Msg ("Test"); };
     virtual void Test(LPCSTR sz) { Msg ("Test"); };
     virtual B() { Msg("Test"); };
     virtual C() { Msg("Test"); };


Зачем это так сделано - военная тайна.
Зачем я это сюда написал - не знаю, не спрашивайте Улыбка
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Превратности VTBL
Ответ #1 - 22. Марта 2007 :: 02:28
Печать  
kms писал(а) 21. Марта 2007 :: 22:37:
Зачем это так сделано - военная тайна.
Зачем я это сюда написал - не знаю, не спрашивайте Улыбка

Причем почти в каждом компиляторе своя военная тайна Улыбка Вот, кстати, товарищ написал статью, а теперь ее злобно ругают, а процессе ругани появляются еще разные любопытные подробности Улыбка
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Превратности VTBL
Ответ #2 - 22. Марта 2007 :: 07:08
Печать  
нет, в MSVC6 вообще как порядок назначается, непонятно.
Сколько с CBLContext::Init маялся, и так, и этак переставлял, все равно не тот
метод из 1С вызывается
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Превратности VTBL
Ответ #3 - 22. Марта 2007 :: 09:15
Печать  
Uzhast писал(а) 22. Марта 2007 :: 02:28:
kms писал(а) 21. Марта 2007 :: 22:37:
Зачем это так сделано - военная тайна.
Зачем я это сюда написал - не знаю, не спрашивайте Улыбка

Причем почти в каждом компиляторе своя военная тайна Улыбка Вот, кстати, товарищ написал статью, а теперь ее злобно ругают, а процессе ругани появляются еще разные любопытные подробности Улыбка

Статья по мне не очень, обсуждение забавное Улыбка
Реализация компиляторо-зависима, это конечно, но неожиданно именно то, что вроде бы общий закон построения для перегруженных функций делает исключение и ставит все с ног на голову Улыбка

orefkov писал(а) 22. Марта 2007 :: 07:08:
нет, в MSVC6 вообще как порядок назначается, непонятно.
Сколько с CBLContext::Init маялся, и так, и этак переставлял, все равно не тот
метод из 1С вызывается


точно! как раз хотел переставить местами (на самом деле в VTBL порядок обратный)

     virtual void InitObject(char const *);      //2722
     virtual void InitObject(class CType const &);      //2721

так ведь нет, пришлось разбираться.

интересно, что не только MSVC6, но и интел 9.1 строит VTBL абсолютно так же при наличии перегруженных методов.
какой-то видать тайный сговор.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
metaeditor
1c++ power user
Отсутствует


are you nuts?

Сообщений: 564
Зарегистрирован: 04. Июля 2006
Пол: Мужской
Re: Превратности VTBL
Ответ #4 - 12. Апреля 2007 :: 15:03
Печать  
наткнулся щас на душещипательную историю по этому же поводу  Улыбка
http://portal.lanpolis.ru/board/index.php?showtopic=2214&st=160#

пост № 192, второй абзац
  

Регистр.EAX.СводныйОстаток()
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Превратности VTBL
Ответ #5 - 13. Апреля 2007 :: 03:52
Печать  
Чтобы не забыть Улыбка продублирую его пост здесь.

http://portal.lanpolis.ru/board/index.php?showtopic=2214&st=160#
Пост 192
Цитата:
Или вот еще ситуация, когда я давно еще пытался скрестить Cbuilder с Visual C++ и у меня вылетал exception когда CBuilderовский клиент создавал экземпляр класса из DLL,написанной в Visual C++ и пытался его использовать. Тогда как если писать клиента на Visual C++ то все работает! Проблема возникла только в том случае, если DLL юзали из Borlandовского клиента!
Проблема заключалась в том, что майкрософтовский компилер, просматривая таблицы виртуальных функций сортирует перегруженные функции так, чтобы они находились рядом. Т.е. для класса:
class Gluck{
virtual C(int a)
virutal SomeFunc()
virtual C(int b,int c)
}
борланд построит виртуальную таблицу так:
C (a)
SomeFunc()
C (b , c)
а майкрософт так:
C(a)
C(b,c)
SomeFunc()
в результате когда борладндовский компилятор работал с виртуальыми функциями и я писал obj->c(b,c), он обращался к третьему слоту в VTBL (майкрософт туда вфигачил SomeFunc()!) и возникла ошибка из за разницы в параметрах.... Если бы количество параметров совпадало, то вообще выполнялась бы соседняя функция без эксепшена! Вот чудеса были бы!
А выяснил я такое различное поведение только путем дизассемблирования работающего клиента и Borland C++-Builderовского.... и понял, что таблицы виртуальных функций MS и Borland строят по разному...
В принципе выход простой - не называть одинаковыми именами виртуальные функции... Но тогда я не знал об этой особенности группировать перегруженные функции у майкрософт! И если бы я не узнал, я бы не сдал в срок прогу
Я вот дизассемблировал и выяснил причину и изменил определение класса заголовочном h файле
с этого

class Gluck{
virtual C(int a)
virutal SomeFunc()
virtual C(int b,int c)
}

вот на такое
class Gluck{
virtual C(int a)
virtual C(int b,int c)
virutal SomeFunc()
}
теперь "одинаковые" функции и так рядом - борланд построит таблицу в соответсвии с определением, а майкрософт не будет их группировать - они уже и так рядом. Я просто перекомпилировал сырцы. Все заработало
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Превратности VTBL
Ответ #6 - 07. Августа 2008 :: 09:48
Печать  
Вот еще попался официальный докУмент: http://support.microsoft.com/kb/131104
  

De quelle planète es-tu?
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Превратности VTBL
Ответ #7 - 07. Августа 2008 :: 10:35
Печать  
ну вообще логично, что функции гупируются..
  
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать