Bug 53899

Summary: [C++0x] undefined reference to std::atomic<boost::lockfree::detail::tagged_ptr...
Product: gcc Reporter: Neil Nelson <nnelson>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal    
Priority: P3    
Version: 4.6.3   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Neil Nelson 2012-07-09 13:35:18 UTC
Thank you for your constantly used GCC compiler.

boost lockfree and boost atomic have been accepted by boost and should shortly be in the boost distribution. The current programs are available at

http://tim.klingt.org/boost_lockfree.tar.gz

The following program when compiled and executed from libs/lockfree/test (including the other required boost distribution components), a folder in the prior gz, will work OK using

g++ bench_3.cpp -o bench_3

but gives errors of the following kind when using 

g++ -std=c++0x bench_3.cpp -o bench_3

undefined reference to `std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long, boost::lockfree::caching_freelist_t, std::allocator<long> >::node> >::load(std::memory_order) const'

undefined reference to `std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long, boost::lockfree::caching_freelist_t, std::allocator<long> >::node> >::compare_exchange_weak(boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long, boost::lockfree::caching_freelist_t, std::allocator<long> >::node>&, boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long, boost::lockfree::caching_freelist_t, std::allocator<long> >::node>, std::memory_order)'

undefined reference to `std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long, boost::lockfree::caching_freelist_t, std::allocator<long> >::node> >::store(boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long, boost::lockfree::caching_freelist_t, std::allocator<long> >::node>, std::memory_order)'

This item may be along the line given in

Bug 49445 [C++0x] Undefined reference to std::atomic<float> "operator float"

Thank you.

Neil

----------------
// bench_3.cpp
#include "../../../boost/lockfree/fifo.hpp"

int elements = 100;
int iterations = 50;

#define FIFO \
    boost::lockfree::fifo<long> f(elements);

#define FIFO_FULL \
    boost::lockfree::fifo<long> f(elements); \
    for (int i = 0; i != elements; ++i) \
        f.enqueue_unsafe(i); \

__attribute__ ((noinline))
__attribute__ ((flatten))
void test_fifo_push(void)
{
    FIFO
    for (int i = 0; i != elements; ++i)
		f.enqueue(i);
}

__attribute__ ((noinline))
__attribute__ ((flatten))
void test_fifo_pop(void)
{
    FIFO_FULL
    long out;
    for (int i = 0; i != elements; ++i)
        f.dequeue(out);
}

int main()
{
    for (int i = 0; i != iterations; ++i)
        test_fifo_push();

    for (int i = 0; i != iterations; ++i)
        test_fifo_pop();
}
Comment 1 Jonathan Wakely 2012-07-09 14:13:12 UTC
(In reply to comment #0)
> This item may be along the line given in
> 
> Bug 49445 [C++0x] Undefined reference to std::atomic<float> "operator float"

It's the same issue, already fixed in 4.7.0

It's not going to be fixed in 4.6, the Boost.lockfree authors will need to change their code to support GCC 4.6

*** This bug has been marked as a duplicate of bug 49445 ***
Comment 2 Jonathan Wakely 2012-07-09 14:30:28 UTC
The lockfree code is invalid anyway because boost::lockfree::detail::tagged_ptr doesn't have a trivial default constructor, so it can't be used with std::atomic
Comment 3 Neil Nelson 2012-07-09 14:34:18 UTC
Redi,

Thank you for your very quick and detailed responses. Looks like I have 
some work to do on my end. I will copy this to the boost lockfree author.

Neil

On 07/09/2012 08:30 AM, redi at gcc dot gnu.org wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53899
>
> --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-07-09 14:30:28 UTC ---
> The lockfree code is invalid anyway because boost::lockfree::detail::tagged_ptr
> doesn't have a trivial default constructor, so it can't be used with
> std::atomic
>
Comment 4 Jonathan Wakely 2012-07-09 14:45:26 UTC
(In reply to comment #2)
> The lockfree code is invalid anyway because boost::lockfree::detail::tagged_ptr
> doesn't have a trivial default constructor, so it can't be used with
> std::atomic

Actually ignore that part - I misread the spec.
Comment 5 Neil Nelson 2012-07-09 16:06:11 UTC
Jonathan, (redi at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org>)

I installed g++-4.7 and obtained a good improvement over the prior 
results with the following output

boost_lockfree/libs/lockfree/test$ g++-4.7 -std=c++0x bench_3.cpp -o bench_3
In file included from /usr/include/boost/lockfree/detail/atomic.hpp:15:0,
                  from ../../../boost/lockfree/fifo.hpp:26,
                  from bench_3.cpp:1:
/usr/include/c++/4.7/atomic: In instantiation of ‘struct 
std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::freelist_node> 
 >’:
/usr/include/boost/lockfree/detail/freelist.hpp:203:29:   required from here
/usr/include/c++/4.7/atomic:160:7: error: function 
‘std::atomic<_Tp>::atomic() [with _Tp = 
boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::freelist_node>]’ 
defaulted on its first declaration with an exception-specification that 
differs from the implicit declaration 
‘std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::freelist_node> 
 >::atomic()’
/usr/include/c++/4.7/atomic: In instantiation of ‘struct 
std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long 
int, boost::lockfree::caching_freelist_t, std::allocator<long int> 
 >::node> >’:
../../../boost/lockfree/fifo.hpp:287:29:   required from ‘class 
boost::lockfree::detail::fifo<long int, 
boost::lockfree::caching_freelist_t, std::allocator<long int> >’
../../../boost/lockfree/fifo.hpp:315:7:   required from ‘class 
boost::lockfree::fifo<long int>’
bench_3.cpp:18:5:   required from here
/usr/include/c++/4.7/atomic:160:7: error: function 
‘std::atomic<_Tp>::atomic() [with _Tp = 
boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long 
int, boost::lockfree::caching_freelist_t, std::allocator<long int> 
 >::node>]’ defaulted on its first declaration with an 
exception-specification that differs from the implicit declaration 
‘std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::detail::fifo<long 
int, boost::lockfree::caching_freelist_t, std::allocator<long int> 
 >::node> >::atomic()’

Tim Blechmann posted on the Boost list this morning he was doing final 
testing for the Boost 51 release. I will copy this to him in case he has 
an idea. My impression is that g++ -std=c++0x and boost lockfree are 
rather close.

Neil

On 07/09/2012 08:45 AM, redi at gcc dot gnu.org wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53899
>
> --- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-07-09 14:45:26 UTC ---
> (In reply to comment #2)
>> The lockfree code is invalid anyway because boost::lockfree::detail::tagged_ptr
>> doesn't have a trivial default constructor, so it can't be used with
>> std::atomic
> Actually ignore that part - I misread the spec.
>
Comment 6 Jonathan Wakely 2012-07-09 16:17:04 UTC
See Bug 53901

I think GCC is correct about that too, the tagged_ptr class template should declare its default constructor and destructor to be noexcept in C++11 mode.