- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is impossible to use construct method from allocators with variadic template.
In TBB v4.3 Update 2 rvalue reference support is detected next way:
#define __TBB_CPP11_RVALUE_REF_PRESENT (__has_feature(__cxx_rvalue_references__) && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION))
I'm using clang 3.6 from sources and not using libcpp, thus it is false. Also _TBB_GCC_VERSION is 4.2.1, so it is less than 40300. So rvalue reference is actually supported by my compiler, but detected as not supported in tbb_config.h.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Usually construct method of an allocator is a thin wrapper over contained type constructor call, i.e. forwarding function:
template<typename U, typename... Args> void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward<Args>(args)...); }
So it relies on presence std::forward function, which internally implemented via r-value references. Usually if C++ compiler supports r-value reference then C++ standard library which comes with it provide std::forward as well.
But, as Clang may use two standard libraries: libc++ and GNU libstdc++, presence of std::forward needed to be checked based on knowing which library is used in fact.
In practice, version of GNU libstdc++ can be bound to version of GCC. Clang defines appropriate GCC version macroses according to version of GCC environment it uses, that is why there are two parts in definition of __TBB_CPP11_RVALUE_REF_PRESENT
: ( __TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION)
So there are several variants to use varaidic version of tbb allocator construct method:
1. Use appropriate C++ standard library (libc++ of any version or libstdc++4.3 or greater, there are some information on compiling Clang with libstdc++ here: http://clang.llvm.org/cxx_status.html )
2. provide your own implementation of std::forward and patch TBB accordingly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I think you misunderstood me. I'm telling that my compiler (clang3.6 built from sources with libstdc++-4.9) do have std::function implemented, but __TBB_GCC_VERSION is 40201 (__GNUC__
, __GNUC_MINOR__
abd __GNUC_PATCHLEVEL__
are hardcoded in clang to 4.2.1). Simply changing that check to __TBB_GCC_VERSION >= 40201 fixes my issue, but this would not work for older libstdc++ versions.
Thus check in TBB for __TBB_CPP11_RVALUE_REF_PRESENT is not correct: __TBB_GCC_VERSION is not related to libstdc++ version at all.
Proper way would be checking __GLIBCXX__, but it doesn't have some simple value we can check against. See also
http://stackoverflow.com/questions/21622561/how-to-detect-the-libstdc-version-in-clang
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok. Now it seen clearly where the problem is. Let see that we can do about it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is there any way to track this issue, or should I add this to TBB bug tracker if it is available anywhere? If not, how do I know if this issue is planned/not planned to be fixed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello George,
Do you have thoughts who it can be detected? if yes, could you submit a patch via our contribution page https://www.threadingbuildingblocks.org/submit-contribution?
--Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey everyone,
The issue described by George is just one symptom of a more general one. Here's a more (but maybe not fully) comprehensive list of macros from tbb_config.h that are undefined/false when using Clang 3.6 with libstdc++ 3.4.20 (shipped with GCC 4.9):
- __TBB_CPP11_RVALUE_REF_PRESENT
- __TBB_CPP11_STD_BEGIN_END_PRESENT
- __TBB_EXCEPTION_PTR_PRESENT
- __TBB_CPP11_TYPE_PROPERTIES_PRESENT
- __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT
- __TBB_MOVE_IF_NOEXCEPT_PRESENT
- __TBB_ALLOCATOR_TRAITS_PRESENT
- __TBB_MAKE_EXCEPTION_PTR_PRESENT
- __TBB_GCC_BUILTIN_ATOMICS_PRESENT
As George mentioned, the proper way would be to check __GLIBCXX__. Its value is a simple int correlated with a GCC version as described on GCC website: https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html . I'm hesitant to submit a patch as I'm afraid there might be cases where relying __TBB_GCC_VERSION value is important for proper detection on other platforms (e.g. with ICC).
Side note: even when __TBB_CPP11_RVALUE_REF_PRESENT is manually set to 1, popping copy-disabled, move-enabled objects from tbb::concurrent_priority_queue still results in a compilation error as __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT is undefined.
![](/skins/images/D2683F18326913BBA0436CB7114DD569/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page