суббота, 2 апреля 2016 г.

[prog.c++] Похоже, наткнулся на баг в С++ компиляторе из Visual Studio 2015 Update 2

Установил себе сегодня Visual Studio 2015 Update 2, попытался скомпилировать SObjectizer. Столкнулся с тем, что перестал работать один из тестов. Тест выбрасывал исключение из функции, которая вызывается из noexcept-функции. Это должно приводить к аварийному завершению теста. Но не приводит.

Грешу на проблему в обновленном VC++, ибо предыдущий компилятор отрабатывал нормально. Грубо говоря, вот такой код:

templatetypename LAMBDA, typename MESSAGE >
class lambda_as_filter_t : public delivery_filter_t
   {
      LAMBDA m_filter;

   public :
      lambda_as_filter_t( LAMBDA && filter )
         :  m_filter( std::forward< LAMBDA >( filter ) )
         {}

      virtual bool
      check(
         const agent_t & /*receiver*/,
         const message_t & msg ) const noexcept override
         {
            return m_filter(message_payload_type< MESSAGE >::payload_reference( msg ));
         }
   };

Должен приводить к краху приложения, если при вызове m_filter(msg) выскакивает исключение. Но не приводит.

Если же сделать вот такой workaround:

templatetypename LAMBDA, typename MESSAGE >
class lambda_as_filter_t : public delivery_filter_t
   {
      LAMBDA m_filter;

      bool
      do_check( const MESSAGE & m ) const noexcept
      {
         return m_filter( m );
      }

   public :
      lambda_as_filter_t( LAMBDA && filter )
         :  m_filter( std::forward< LAMBDA >( filter ) )
         {}

      virtual bool
      check(
         const agent_t & /*receiver*/,
         const message_t & msg ) const noexcept override
         {
            return do_check(message_payload_type< MESSAGE >::payload_reference( msg ));
         }
   };

То все начинает работать так, как и ожидалось: приложение падает.

Подозреваю, что здесь сказывается то, что базовый класс, delivery_filter_t, из которого наследуется метод check(), экспортируется из DLL. А конкретные экземпляры lambda_as_filter_t генерируются внутри приложение, которое линкует эту DLL. Но пока минимального примера, явно указывающего наличие этой проблемы, сделать не удалось (я пробовал без DLL-ек, но баг не проявился). Может, однако, еще какие-то проблемы сказываются.

В общем, неприятная штука. Как бы не пришлось себе откатывать VS на Update1.

Upd. Засабмитил в Microsoft. Посмотрим, что ответят. И ответят ли.

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