четверг, 1 декабря 2011 г.

C++ библиотека-плагин для Unix. Часть 6-я. Локальные статические объекты и чем они страшны.

См. Бьeрн Страустрап. Справочное руководство по C++
Все так и работает, как Страустрап прописал. Но однажды столкнулись со следующей проблемой:
Используя boost::spirit, богатую выражениями вида:
//spirit\home\classic\core\primitives\impl\numerics.ipp
  static RT parse(ScannerT const& scan)
            {
                static self_t this_;
                return impl::implicit_lexeme_parse<RT>(this_, scan, scan);
            }
          
столкнулись со странными падениями при обращении нашей библиотеки к локальным статическим объектам. Дело это было на нашем любимом HP-UX и главное приложение, вызывающее (через dl_open) нашу библиотеку собрано на aCC. При таком раскладе конструкторы локальных статических объектов не вызываются. Пришлось spirit патчить на предмет всех локальных статиков, типа:
static boost::shared_ptr<object_with_id_base_supply<IdT> > static_supply;
                if (!static_supply.get())
                    static_supply.reset(new object_with_id_base_supply<IdT>());
                id_supply = static_supply;

заменяем на синглтон из ACE:
#define BOOST_SPIRIT_SINGLE_PTR(T)\
 (* ACE_Singleton<T, ACE_Thread_Mutex>::instance())
... 
boost::shared_ptr<object_with_id_base_supply<IdT> >& static_supply =
 BOOST_SPIRIT_SINGLE_PTR(
  boost::shared_ptr<object_with_id_base_supply<IdT> >
);
if (!static_supply.get())
  static_supply.reset(new object_with_id_base_supply<IdT>());
  id_supply = static_supply;
Ну и так далее.Кстати, у Clang есть опция -Wexit-time-destructors, предупреждающая, о том, что глобальные объекты вызывают деструкторы. Надо будет как нибудь попробовать.


Комментариев нет:

Отправить комментарий