Сбой CppCheck с определенным синтаксисом шаблона

в нашем проекте (VS С++ 17) у нас есть шаблон, из-за которого CppCheck (версия 1.89, а также некоторые более ранние версии) не приводит к сбою Windows.

Он аварийно завершает работу при вызове из командной строки или через графический интерфейс. К сожалению, инструмент выходит так, что я не могу понять, почему он падает. Через графический интерфейс я попытался установить версию С++ на 14, 17 и 20, но безрезультатно.

После проверки файла, вызвавшего сбой, я определил, что следующий синтаксис в заголовке является «виновным»:

// Header file

template <
    class obj_type,
    template<class> class allocator = SmartPointerAllocator,
    template<class, class> class data_container = std::list>

class EXPORT_OBJECT GenericConfigurationHandler 
{
protected:
    typedef typename allocator<obj_type>::ClientData ClientData;
    typedef data_container<ClientData, std::allocator<ClientData>> TargetConfigurations;
private:
    mutable TargetConfigurations m_target_configurations;

protected:
    TargetConfigurations& get_target_configurations() const { return m_target_configurations; }

public:
    /**
    *   \brief constructor
    */
    GenericConfigurationHandler() = default;

    /**
    *   \brief destructor
    */
    virtual ~GenericConfigurationHandler() {
        std::for_each(m_target_configurations.begin(), m_target_configurations.end(),
            [](ClientData& data) {
            allocator<obj_type>::destroy(data);
        });
    }

    /**
    *   \brief regist a new configuration
    *   \param target_config new target configuration
    */
    template <class src_obj>
    void regist_configuration(const src_obj& target_config) {
        m_target_configurations.push_back(allocator<obj_type>::create(target_config));
    }

    /**
    *   \brief generates target configuration values
    */
    virtual TargetConfigurations build_configurators() const {
        return m_target_configurations;
    }
};

Сам SmartPointerAllocator:

// Header file
template<class T>
struct SmartPointerAllocator {
    //variable type
    typedef typename std::remove_pointer<T>::type var_type;
    //conatiner type
    typedef std::shared_ptr<var_type> ClientData;

    //creator
    template<class obj_type>
    static ClientData create(const obj_type& src_obj) {
        typedef typename std::remove_pointer<obj_type>::type src_obj_type;
        return ClientData(new src_obj_type(src_obj));
    }

    //deallocator
    static void destroy(ClientData& src_obj) {
    }

    static void commit(const ClientData& src_obj) {
        src_obj->commit_configuration();
    }
};

Еще я заметил, что сбой возникает при загрузке файлов .cpp и чтении/разборе файлов .h. Не во время анализа!

Если я прокомментирую определение шаблона и оставлю "не компилируемый код" таким образом, анализ будет пройден:

// Header file

//template <
//  class obj_type,
//  template<class> class allocator = SmartPointerAllocator,
//  template<class, class> class data_container = std::list>

class EXPORT_OBJECT GenericConfigurationHandler 
{
protected:
    typedef typename allocator<obj_type>::ClientData ClientData;
    typedef data_container<ClientData, std::allocator<ClientData>> TargetConfigurations;
private:
    mutable TargetConfigurations m_target_configurations;

protected:
    TargetConfigurations& get_target_configurations() const { return m_target_configurations; }

public:
    /**
    *   \brief constructor
    */
    GenericConfigurationHandler() = default;

    ...
};

Разница между первым и третьим кодом заключается только в закомментированных строках шаблона в начале.

Я пытался скрыть конкретный заголовочный файл, но инструмент не позволяет (только файлы cpp)

Любые предложения, как преодолеть это?


person Mladen Milev    schedule 09.10.2019    source источник
comment
Возможно, просто отправьте отчет об ошибке в cppcheck.   -  person Alan Birtles    schedule 09.10.2019
comment
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что это отчет об ошибке для cppcheck.   -  person rubenvb    schedule 09.10.2019
comment
Используйте анализаторы, поддерживающие C++17 :). Например, PVS-Studio (бесплатная лицензия).   -  person user34341    schedule 09.10.2019
comment
Черт, я разместил тему здесь, и мои последние 2 строки сообщения являются важными: поиск обмена знаниями и инициирование обсуждения для эффективного и/или контролируемого использования и сканирования кода с помощью CppCheck. Поэтому, пожалуйста, не закрывайте тему, а сосредоточьтесь на обмене знаниями по использованию инструмента и C++. Что касается бесплатного PVS-Studio, то, кроме бесплатного маркетинга, в моем случае он неприменим, и у меня CppCheck интегрирован с Sonar.   -  person Mladen Milev    schedule 10.10.2019
comment
Возможно, cppcheck не обрабатывает синтаксис template<class> class allocator и требует template<typename> class allocator.   -  person Jarod42    schedule 11.10.2019


Ответы (1)


Вы можете определить MACRO для cppcheck (например, включить защиту файла заголовка).

Или что-то более конкретное:

#if !defined(CPP_CHECK)
template <
  class obj_type,
  template<class> class allocator = SmartPointerAllocator,
  template<class, class> class data_container = std::list>
#endif
class EXPORT_OBJECT GenericConfigurationHandler
{
    // ...
};

а потом

cppcheck -DCPP_CHECK file.cpp

person Jarod42    schedule 09.10.2019
comment
Вы можете привести мне пример? Я не увидел в мануале CppCheck, как в коде cpp определить микрос, чтобы код исключался - person Mladen Milev; 10.10.2019
comment
@MladenMilev: добавлен пример. - person Jarod42; 10.10.2019
comment
Спасибо, но, к сожалению, все еще вылетает :( - person Mladen Milev; 10.10.2019
comment
CppCheck распознает имя MACRO. Возможно ли, что проблема в том, что макрос находится внутри включенного заголовка? Не должно быть так, как должно расширять заголовок в классе. Но, с другой стороны, он не компилируется, поэтому может обрабатывать его отдельно от класса. - person Mladen Milev; 10.10.2019
comment
Как часто я путаю условие проверки. должно быть исправлено сейчас. - person Jarod42; 10.10.2019
comment
Это работает! Большое спасибо за помощь, и сегодня я узнал что-то новое! Отличная работа! @Джарод42 - person Mladen Milev; 11.10.2019