BugTraq.Ru
Русский BugTraq
https://bugtraq.ru/lj/archive/2011/2903.1434.html

классвьюшнопобедное
29.03.11 14:34 // оригинал
При разборе косяков с ClassView в 2010-й студии было сразу понятно, что предпосылки проблемы восходят к тем уже далеким временам, когда один здоровый монолитный проект был разнесен по десятку dll. Первый подход был кривоват, полезли перекрестные ссылки подпроектов, которые через некоторое время пришлось разрулить железной рукой, при этом поперли кросс-ссылки инклюдов, которые разруливались в основном через активное использование forward-описаний классов (что, конечно, подпорки, но гораздо проще и быстрее долгого выстраивания правильного порядка инклюдов - опять же, не всегда достижимого).

В сочетании же с пространствами имен простое forward-описание приходится превращать в более громоздкие конструкции. Т.е., если в MyClass1 используется указатель на MyClass2, а живут они в разных пространствах имен, выглядеть это будет так:

namespace NS2
{
class MyClass2;
}

namespace NS1
{
class MyClass1
{
//...
MyClass2* m_pXXX;
};
}

Кроме того, в описании классов/функций из dll активно использовался вполне традиционный подход с выносом __declspec(dllexport/dllimport) в макросы, чтоб убрать поддержку двух наборов хедеров:

#ifdef MYDLLIMP
#define MYDLLEXP __declspec(dllexport)
#else
#define MYDLLEXP __declspec(dllimport)
#endif

После чего можно использовать это как

class MYDLLEXP MyClass
{
//...
};

MYDLLIMP определялся только в проекте, где класс нужно было экспортировать, так что в реализации класс оказывался с dllexport, а в пользовательских проектах с dllimport.

Именно эти две вещи и сломали ClassView. Крышеснос с непопаданием в место с описанием случился от MYDLLEXP - ну не врубался новый IntelliSense в эти макросы между ключевым словом class и именем класса. Пришлось чуть подправить:

#ifdef MYDLLIMP
#define MYDLLEXP dllexport
#else
#define MYDLLEXP dllimport
#endif

class __declspec(MYDLLEXP) MyClass
{
//...
};

Теперь все стало лучше, __declspec все-таки воспринимался как валидное ключевое слово, а что там внутри него, ClassView, к счастью, не волновало.

Ну а дубли в дереве возникли от сочетания forward-описаний с пространствами имен - каждое такое описание добавляло лишнюю строчку в дерево классов. Причем дубль возникал даже при описании дружественного класса из того же пространства имен:

namespace NS1
{
class MyClass1
{
friend class MyClass3;
};
}

Причина была понятна сразу, на устранение ушло несколько месяцев неспешных поисков (поскольку жить это особо не мешает, лишь тревожит чувство прекрасного).

Сначала искал подходящие настройки, потом подходящие прагмы, остановился же в итоге на следующем варианте, за который даже немного стыдно:

//stdafx.h
#ifndef __class
#define __class class
#define __struct struct
#endif

//myclass1.h
namespace NS2
{
__class MyClass2;
}

namespace NS1
{
class MyClass1
{
friend __class MyClass3;
//...
MyClass2* m_pXXX;
};
}


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

 
теги: софт, программизм  |  обсудить  |  все отзывы (0)  |  обсудить в LJ [1786]
назад «  » вперед

аналогичные материалы
макоудаленное // 29.01.24 23:10
разнонедельное // 07.12.23 15:09
qtменюшное // 29.09.23 23:47
тейлскейлное // 18.04.23 20:43
ютубноподкастное // 15.10.22 22:07
дваждыодиннадцатое // 22.06.22 03:30
безоблачнопарольное // 22.03.22 23:05
стартофинишное // 24.10.21 03:59
meshное // 06.08.21 20:06
яблочнопереключальное // 26.07.20 17:07
 
последние записи
песчаное // 13.03.24 18:05
макоудаленное // 29.01.24 23:10
разнонедельное // 07.12.23 15:09
qtменюшное // 29.09.23 23:47
неестественноинтеллектуальное // 29.09.23 16:50
основательное // 18.09.23 00:15
отпускное // 06.08.23 00:26
вчерашнезавтрашнее // 02.07.23 15:25
позитивное // 27.06.23 13:05
тейлскейлное // 18.04.23 20:43





  Copyright © 2001-2024 Dmitry Leonov Design: Vadim Derkach