[cfe-dev] libc++: help diagnosing the following std::atomic compile error

Richard Smith richard at metafoo.co.uk
Mon May 20 13:44:03 PDT 2013


On Mon, May 20, 2013 at 1:02 PM, Howard Hinnant <hhinnant at apple.com> wrote:

> On May 20, 2013, at 3:29 PM, Rich E <reakinator at gmail.com> wrote:
>
> > Hello all,
> >
> > I am trying to help along the recently added Boost.Lockfree (1) library
> utilize libc++'s std::atomic, as it is currently using Boost.Atomic, and an
> emulated, locking implementation at that.  <atomic> is currently used for
> this library for modern gcc and msvc compilers, but not yet clang / libc++.
> >
> >
> > (note: to enable <atomic> for boost::lockfree, first apply this patch:
> https://svn.boost.org/trac/boost/attachment/ticket/8593/lockfree_atomic_libcpp.patch)
> >
> > The problem can be seen in the compile errors for this simple program:
> >
> > #include "boost/lockfree/queue.hpp"
> >
> > int main(int argc, const char * argv[])
> > {
> >   boost::lockfree::queue<int> q( 1 );
> >   return 0;
> > }
> >
> > The diagnostic is:
> >
> > In file included from
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:606:
> >
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/atomic:623:58:
> error: no viable conversion from
> 'boost::lockfree::detail::tagged_ptr<boost::lockfree::queue<int,
> boost::parameter::void_, boost::parameter::void_,
> boost::parameter::void_>::node>' to
> '_Atomic(boost::lockfree::detail::tagged_ptr<boost::lockfree::queue<int,
> boost::parameter::void_, boost::parameter::void_,
> boost::parameter::void_>::node>)'
> >     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
> >                                                          ^    ~~~
> >
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/atomic:727:51:
> note: in instantiation of member function
> 'std::__1::__atomic_base<boost::lockfree::detail::tagged_ptr<boost::lockfree::queue<int,
> boost::parameter::void_, boost::parameter::void_,
> boost::parameter::void_>::node>, false>::__atomic_base' requested here
> >     _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
> >                                                   ^
> > ../../../../../cinder-dev/boost/boost/lockfree/queue.hpp:192:9: note: in
> instantiation of member function
> 'std::__1::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::queue<int,
> boost::parameter::void_, boost::parameter::void_,
> boost::parameter::void_>::node> >::atomic' requested here
> >         head_(tagged_node_handle(0, 0)),
> >         ^
> >
> /Users/richeakin/code/cinder/audio-rewrite/audio2/test/BasicTest/xcode/../src/BasicTestApp.cpp:75:30:
> note: in instantiation of member function 'boost::lockfree::queue<int,
> boost::parameter::void_, boost::parameter::void_,
> boost::parameter::void_>::queue' requested here
> >         boost::lockfree::queue<int> q( 1 );
> >                                     ^
> >
> ../../../../../cinder-dev/boost/boost/lockfree/detail/tagged_ptr_dcas.hpp:112:5:
> note: candidate function
> >     operator bool(void) const
> >     ^
> >
> >
> > My understanding is (please correct me if wrong) that _Atomic(_Tp) is a
> directive to the compiler, which is replaced with atomic the true atomic
> instructions for each given architecture. As such, it doesn't know how to
> replace boost::lockfree::detail::tagged_ptr<...> with size_t, or whatever
> other atomic value lockfree expects. But, this is where my understanding of
> this sort of template metaprogramming reaches its end, I just can't tell
> why this trips up with libc++ but not with vc11.
> >
> > Can anyone see where the translation falls short, or have suggestions on
> how to proceeed?
>
> This looks like a clang bug to me.  _Atomic seems to not be set up to deal
> with non-integral types.
>

I don't think this is clearly a clang bug. We support _Atomic(T) in C++
mode as an extension, but that extension currently does not extend to
allowing an _Atomic(T) to be initialized as if it were a T, if T is of
class type. We can only reasonably support this when T's corresponding
constructor is trivial, but I believe that's all you actually need here,
right? (We don't want to allow calling member functions on an object of
type T which is wrapped within an _Atomic(...)).

Here is a simplified version of Rich's test:
>
> #include <atomic>
>
> struct A
> {
>     A(int) {}
> };
>
> int
> main()
> {
>     std::atomic<A> q(A(1));
> }
>
> Howard
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130520/a1d2f9c5/attachment.html>


More information about the cfe-dev mailing list