Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Intel compiler chokes on template instantiation

Ruben_V_
Beginner
510 Views

I have written code that compiles fine on GCC 6.2, clang 3.9, and MSVS 2015 (the C++ build tools version).

It's available on github:
https://www.github.com/rubenvb/skui

Build with the following define to skip building Skia and head straight for the error:

cmake -DSKIP_SKIA=TRUE -DCMAKE_CXX_COMPILER=icpc
make

You'll need Linux with XLib/XCB installed and findable by the compiler.

The error is as follows:

/home/ruben/Development/skui/core/value_ptr.h++(50): error: object of abstract class type "skui::core::implementation::slot<void>" is not allowed:
            function "skui::core::implementation::slot<ReturnType, ArgTypes...>::operator() [with ReturnType=void, ArgTypes=<>]" is a pure virtual function
               { return static_cast<void*>(new T(*static_cast<T*>(other))); };
                                               ^
          detected during:
            instantiation of "void *(*skui::core::copy_constructor_copier<T>())(void *) [with T=skui::core::implementation::slot<void>]" at line 69
            instantiation of "skui::core::smart_copy<T>::smart_copy() [with T=skui::core::implementation::slot<void>]" at line 140

/home/ruben/Development/skui/core/value_ptr.h++(59): error: static assertion failed with "Cannot default construct smart_copy for an abstract type."
        explicit smart_copy() { static_assert(!std::is_abstract<T>::value, "Cannot default construct smart_copy for an abstract type."); }
                                ^
          detected during instantiation of "skui::core::smart_copy<T>::smart_copy() [with T=skui::core::implementation::slot<void>]" at line 140

/home/ruben/Development/skui/core/value_ptr.h++(50): error: object of abstract class type "skui::core::implementation::slot<void, skui::core::string>" is not allowed:
            function "skui::core::implementation::slot<ReturnType, ArgTypes...>::operator() [with ReturnType=void, ArgTypes=<skui::core::string>]" is a pure virtual function
               { return static_cast<void*>(new T(*static_cast<T*>(other))); };
                                               ^
          detected during:
            instantiation of "void *(*skui::core::copy_constructor_copier<T>())(void *) [with T=skui::core::implementation::slot<void, skui::core::string>]" at line 69
            instantiation of "skui::core::smart_copy<T>::smart_copy() [with T=skui::core::implementation::slot<void, skui::core::string>]" at line 140
            instantiation of class "skui::core::value_ptr<T, Copier, Deleter> [with T=skui::core::implementation::slot<void, skui::core::string>, Copier=skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, Deleter=std::default_delete<skui::core::implementation::slot<void, skui::core::string>>]" at line 72 of "/usr/include/c++/6.2.1/bits/list.tcc"
            instantiation of "void std::__cxx11::_List_base<_Tp, _Alloc>::_M_clear() [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *,
                      skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 442 of "/usr/include/c++/6.2.1/bits/stl_list.h"
            instantiation of "std::__cxx11::_List_base<_Tp, _Alloc>::~_List_base() [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *,
                      skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 62 of "/home/ruben/Development/skui/core/signal.h++"
            implicit generation of "std::__cxx11::list<_Tp, _Alloc>::~list() [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void,
                      skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 62 of "/home/ruben/Development/skui/core/signal.h++"
            instantiation of class "std::__cxx11::list<_Tp, _Alloc> [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void,
                      skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 62 of "/home/ruben/Development/skui/core/signal.h++"
            instantiation of "skui::core::implementation::signal_base<ArgTypes...>::~signal_base() [with ArgTypes=<skui::core::string>]" at line 191 of "/home/ruben/Development/skui/core/signal.h++"

/home/ruben/Development/skui/core/value_ptr.h++(59): error: static assertion failed with "Cannot default construct smart_copy for an abstract type."
        explicit smart_copy() { static_assert(!std::is_abstract<T>::value, "Cannot default construct smart_copy for an abstract type."); }
                                ^
          detected during:
            instantiation of "skui::core::smart_copy<T>::smart_copy() [with T=skui::core::implementation::slot<void, skui::core::string>]" at line 140
            instantiation of class "skui::core::value_ptr<T, Copier, Deleter> [with T=skui::core::implementation::slot<void, skui::core::string>, Copier=skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, Deleter=std::default_delete<skui::core::implementation::slot<void, skui::core::string>>]" at line 72 of "/usr/include/c++/6.2.1/bits/list.tcc"
            instantiation of "void std::__cxx11::_List_base<_Tp, _Alloc>::_M_clear() [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *,
                      skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 442 of "/usr/include/c++/6.2.1/bits/stl_list.h"
            instantiation of "std::__cxx11::_List_base<_Tp, _Alloc>::~_List_base() [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *,
                      skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 62 of "/home/ruben/Development/skui/core/signal.h++"
            implicit generation of "std::__cxx11::list<_Tp, _Alloc>::~list() [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void,
                      skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 62 of "/home/ruben/Development/skui/core/signal.h++"
            instantiation of class "std::__cxx11::list<_Tp, _Alloc> [with _Tp=std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void, skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>, _Alloc=std::allocator<std::pair<const skui::core::trackable *, skui::core::value_ptr<skui::core::implementation::slot<void,
                      skui::core::string>, skui::core::smart_copy<skui::core::implementation::slot<void, skui::core::string>>, std::default_delete<skui::core::implementation::slot<void, skui::core::string>>>>>]" at line 62 of "/home/ruben/Development/skui/core/signal.h++"
            instantiation of "skui::core::implementation::signal_base<ArgTypes...>::~signal_base() [with ArgTypes=<skui::core::string>]" at line 191 of "/home/ruben/Development/skui/core/signal.h++"

compilation aborted for /home/ruben/Development/skui/core/application.c++ (code 2)

I have absolutely no idea why it fails, and the fact that three other independent compilers like the code as it is (with /W4 or -Wextra -pedantic warning free) points me in the direction of a compiler bug. Am I right or is there a subtlety in the code I have written?

0 Kudos
5 Replies
Melanie_B_Intel
Employee
510 Views

Yes this is a compiler bug. I've opened DPD200417007 in our internal bug tracking database.  Thanks for reporting it, and thanks for attaching the self-contained reproducer.

 --Melanie

0 Kudos
Ruben_V_
Beginner
510 Views

Any updates on this? I have received 2-3 compiler updates, each time hoping this issue would be fixed.

I'd really like to start using the Intel compiler for my project (and add it to the supported list). As this is failing on a core component, I cannot work around it, nor do I see a way to bypass this deficiency without refactoring all of the involved code.

Thanks for all the great work anyway!

0 Kudos
Melanie_B_Intel
Employee
510 Views

We don't have a solution for this yet.  I'll see if I can get some more information. --Melanie

0 Kudos
Judith_W_Intel
Employee
510 Views

A possible workaround is to change the defaulted constructor in value_ptr to an empty constructor, i.e. change the code under #ifdef OK below:

 

    template<typename T,

             typename Copier = smart_copy<T>,

             typename Deleter = std::default_delete<T>>

    class value_ptr

    {

      using pointer = std::add_pointer_t<T>;

      using element_type = std::remove_reference_t<T>;

      using reference = std::add_lvalue_reference_t<element_type>;

      using const_reference = std::add_const_t<reference>;

      using copier_type = Copier;

      using deleter_type = Deleter;

    public:

#ifdef OK

      explicit constexpr value_ptr() {};

#else

      explicit constexpr value_ptr() = default;

#endif

 

It doesn’t look like there are any data members that need initialization inside the constructor (data is already initialized inline) so just an empty constructor would I think be equivalent.

 

We are working on a fix - probably by the next 17.0 update. Thanks for your patience.

Judy

 

0 Kudos
Ruben_V_
Beginner
510 Views

Thanks, the workaround is simple enough and works as advertised.

 

Thanks for the strong communication!

0 Kudos
Reply