Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
Announcements
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.

Error compiling pipeline.h with Clang

Blue_Sky_Studios
Beginner
487 Views

I ran into this error compiling an application with TBB 4.1.4 and Clang++ 3.3:

In file included from [snip]/tbb/tbb.h:67:
[snip]/tbb/pipeline.h:348:74: error: no template named
      'is_trivially_copyable' in namespace 'std'; did you mean 'tbb_trivially_copyable'?
template<typename T> struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable<T>::value }; };
                                                                    ~~~~~^~~~~~~~~~~~~~~~~~~~~
                                                                         tbb_trivially_copyable
/netDISKS/master/netmt/LINUX_INTF14C/cgi/intel_tbb/4.1.4/Include/libtbb/tbb/pipeline.h:348:29: note: 'tbb_trivially_copyable' declared here
template<typename T> struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable<T>::value }; };
                            ^
/netDISKS/master/netmt/LINUX_INTF14C/cgi/intel_tbb/4.1.4/Include/libtbb/tbb/pipeline.h:348:100: error: no member named 'value' in
      'tbb_trivially_copyable<T>'
template<typename T> struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable<T>::value }; };
                                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

I fixed the header with this:

@@ -342,7 +342,7 @@
 template<> struct tbb_trivially_copyable <float> { enum { value = !tbb_large_object<float>::value }; };
 template<> struct tbb_trivially_copyable <double> { enum { value = !tbb_large_object<double>::value }; };
 #else
-#if __GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__
+#if (__GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__) || __clang_major__ >= 3
 template<typename T> struct tbb_trivially_copyable { enum { value = std::has_trivial_copy_constructor<T>::value }; };
 #else
 template<typename T> struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable<T>::value }; };

I have no idea what version of Clang++ is appropriate to detect the change from is_trivially_copyable to has_trivial_copy_constructor.  I found that tbb_config.h sets TBB_IMPLEMENT_CPP0X to 0 for Clang++ in line 251.  Perhaps similar logic is needed in pipeline.h.

0 Kudos
7 Replies
RafSchietekat
Black Belt
487 Views

The source code states that it "cannot use SFINAE in current compilers", but I suppose that "type traits" was meant instead: this requires SFINAE (a given since C++03 if I am not mistaken), but SFINAE is insufficient to accurately implement all type traits.

And, considering that even a multi-megabyte object could be trivially copyable, why compare with the size of a pointer? It's not even relevant because tbb_trivially_copyable is only used in is_large_object, which has a separate test for tbb_large_object, but which should also be renamed to reflect what it actually means.

TBB_IMPLEMENT_CPP0X seems to have several problems: it means the opposite of what you would suspect, but then seems to reverse that again with regard to <thread> and <condition_variable>, and may be incomplete. What's needed here is a test for <type_traits> availability and functionality. I would recommend adding __TBB_CPP11_TYPE_TRAITS_PRESENT to tbb_config.h, and either using that instead of TBB_IMPLEMENT_CPP0X in pipeline.h or using part of my recent contribution incorporating a more complete implementation of is_trivially_copyable. Note that __has_include(<type_traits>) was not enough the last time I tried this on OS X, but I have not explored this further, including whether it depends on the use of libc++, which is not the default with TBB even with compiler=clang.

Anton_P_Intel
Employee
487 Views

hadsell, could you please specify compiler switches used?  

Anton_P_Intel
Employee
487 Views

Raf, could you please elaborate that problems did you faced on OS X with  __has_include(<type_traits>) ? IIRC gcc 4.1 should have type_traits under tr1 folder and probably Clang should not detect it via __has_include.

Blue_Sky_Studios
Beginner
487 Views

For an optimized compile:

-march=core2 -msse4.1 -m64 -std=c++0x -fPIC -pthread -gcc-toolchain /opt/gcc-4.7.2 -Wno-logical-op-parentheses -Wno-shift-op-parentheses -O2

RafSchietekat
Black Belt
487 Views

In the code I submitted yesterday, if I enable the test for __has_include(<type_traits>) at tbb_config.h:114, I get a compiler crash, even if I add "-std=c++11 -stdlib=libc++" (without the quotes) to CPLUS_FLAGS in macos.clang.inc. From inside Xcode in a simple test program I can set such a switch, #include <type_traits>, and evaluate std::is_trivially_copyable<float>(), but not with TBB from the command line. I haven't tried to use TBB from inside Xcode yet.

Blue_Sky_Studios
Beginner
487 Views

Today I started to upgrade from TBB 4.1 update 4 to 4.2 update 3.  I found the same problem with pipeline.h.  I had to apply the same fix for compiling with Clang++:

diff -u -r1.1 -r1.2
--- pipeline.h    28 Apr 2014 21:27:20 -0000    1.1
+++ pipeline.h    28 Apr 2014 22:35:54 -0000    1.2
@@ -342,7 +342,7 @@
 template<> struct tbb_trivially_copyable <float> { enum { value = !tbb_large_object<float>::value }; };
template<> struct tbb_trivially_copyable <double> { enum { value = !tbb_large_object<double>::value }; };
#else
-#if __GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__
+#if (__GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__) || __clang_major__ >= 3
template<typename T> struct tbb_trivially_copyable { enum { value = std::has_trivial_copy_constructor<T>::value }; };
#else
template<typename T> struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable<T>::value }; };

 

Alexey_K_Intel3
Employee
487 Views

The bug is fixed in recently released version 4.3.

Reply