2014-10-16 13 views
9

EDIT:allocators Boost hồ bơi sẽ không biên dịch với std :: allocate_shared trong g ++

Làm rõ kết quả mong muốn của tôi bởi vì tôi đã không truyền đạt nó cũng:
Để có thể sử dụng std::allocate_shared với boost::fast_pool_allocator như phương pháp phân bổ sử dụng g ++ 4.8 hoặc cao hơn với boost 1.56.0. Hiện tại, nó hoạt động trên g ++ 4.6 và không thành công trên 4.7, 4.8 và 4.9.

Để rõ ràng, tôi không muốn có công việc này cho g ++ 4.7.

đang thử nghiệm để sản xuất lỗi:

#include "boost/pool/pool.hpp" 
#include "boost/pool/pool_alloc.hpp" 

#include <memory> 

int main(int argc, char** argv) 
{ 
    auto fails = std::allocate_shared<int>(boost::fast_pool_allocator<int>()); 

    auto works = std::allocate_shared<int>(boost::fast_pool_allocator<int>(), 5); 
} 

Trong cơ sở mã của chúng tôi, chúng tôi có sử dụng std :: allocate_shared kết hợp với allocators hồ bơi tăng và kết quả này trong một số lỗi biên dịch khó chịu. Tuy nhiên điều này đã biến dạng và thay đổi trên các phiên bản khác nhau của g ++:
chi tiết: 64bit, (4.7,4.8) -std = C++ 11, (4.6) -std = C++ 0x, tăng 1.56.0
4.6 - biên dịch hạnh phúc
4.7 - Crashes trình biên dịch

Internal compiler error: Error reporting routines re-entered. Please submit a full bug report, with preprocessed source if appropriate. See for instructions. Preprocessed source stored into /tmp/cca0Emq9.out file, please attach this to your bugreport.

4,8 - lỗi biên dịch Nasty

/XXXXXXXXXX/boost/boost/pool/pool_alloc.hpp:399: 

error: use of deleted function ‘std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2u>::_Sp_counted_ptr_inplace(const std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2u>&)’ { new (ptr) T(t); } ^

/usr/include/c++/4.8/bits/shared_ptr_base.h:198: error: ‘std::_Sp_counted_base<_Lp>::_Sp_counted_base(const std::_Sp_counted_base<_Lp>&) [with __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’ is private _Sp_counted_base(_Sp_counted_base const&) = delete; ^ /usr/include/c++/4.8/bits/shared_ptr_base.h:379: error: within this context class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> ^

/usr/include/c++/4.8/bits/shared_ptr_base.h:379: error: use of deleted function ‘std::_Sp_counted_base<_Lp>::_Sp_counted_base(const std::_Sp_counted_base<_Lp>&) [with __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’

/usr/include/c++/4.8/bits/shared_ptr_base.h:198: error: declared here _Sp_counted_base(_Sp_counted_base const&) = delete; ^

4,9 - lỗi Nasty biên dịch (hơi khác nhau)

/XXXXXXXXXXX/boost/boost/pool/pool_alloc.hpp:399: error: use of deleted function ‘std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2u>::_Sp_counted_ptr_inplace(const std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2u>&)’ { new (ptr) T(t); } ^

/usr/include/c++/4.9/bits/shared_ptr_base.h:203: error: ‘std::_Sp_counted_base<_Lp>::_Sp_counted_base(const std::_Sp_counted_base<_Lp>&) [with __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’ is private _Sp_counted_base(_Sp_counted_base const&) = delete; ^

/usr/include/c++/4.9/bits/shared_ptr_base.h:494: error: within this context class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> ^

/usr/include/c++/4.9/bits/shared_ptr_base.h:494: error: use of deleted function ‘std::_Sp_counted_base<_Lp>::_Sp_counted_base(const std::_Sp_counted_base<_Lp>&) [with __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’

Tôi đã dành một số lượng đáng kể thời gian cố gắng để đến đáy của điều này và tôi một số hỗ trợ sẽ được đánh giá cao nếu có ai quen thuộc hơn với hoạt động bên trong của các thành phần này.

+4

Lỗi trình biên dịch nội bộ là _always_ lỗi có thể báo cáo cho nhà cung cấp, SO không thể trợ giúp điều đó. – sehe

+0

Tôi có một linh cảm này là nhiều hơn một thay đổi thư viện chuẩn hơn là một sự thay đổi trình biên dịch. – sehe

+1

Theo đề xuất của @Sehe, đây là một vấn đề với việc thực hiện thư viện chuẩn thay vì trình biên dịch. Tôi đã thử điều này trong (GCC) 5.0.0 20141022 (thử nghiệm) và nó biên dịch. –

Trả lời

3

Tôi đã dành rất nhiều thời gian xem xét các phiên bản trình biên dịch khác nhau theo giả định rằng đây là lỗi trình biên dịch theo đề xuất của sự cố trong g ++ 4.7 và nhận xét của người trả lời/người nhận xét khác. Tuy nhiên sau khi quay trở lại các lỗi biên dịch và đào bới chúng trong một thời gian, cuối cùng tôi đã hiểu được nguyên nhân của các lỗi biên dịch với một mức độ cụ thể nào đó.

Vì vậy, vấn đề thực sự nằm trong số boost::fast_pool_allocatorboost::pool_allocator và có vẻ như một chút hiển nhiên khi nhìn lại. Điểm mấu chốt cơ bản của vấn đề là tăng allocators construct method được thực hiện theo tiêu chuẩn phân bổ tiêu chuẩn C++ 98 và có phương thức xây dựng lấy một tham số & const duy nhất được sử dụng để sao chép xây dựng một đối tượng trong một vị trí mới. Kiểu C++ 11 sử dụng các mẫu variadic và các arg được truyền cho một hàm tạo cho đối tượng được tạo thông qua vị trí mới. Trong trường hợp cụ thể của mã thử nghiệm của tôi, nó là biến thể không chuyển giá trị khởi tạo đến std::allocate_shared gây ra lỗi.Vấn đề cốt lõi trong tầm tay là C++ 11 std::allocate_shared đang cố gắng chuyển một số biến số đối số sang phương thức construct() chỉ mất một. Trong các thử nghiệm của tôi, tôi có thể phá vỡ phương thức xây dựng khi có chính xác một giá trị được truyền vào và nó không được gọi cho các biến thể khác. Ví dụ nếu bạn đang phân bổ một std::pair<> (2 params) thì phương thức xây dựng không được gọi là gì cả và phải sử dụng một số cơ chế khác. Tôi truy tìm này một chút và có vẻ như std::allocate_shared kết thúc cuộc gọi xây dựng nội bộ và nếu lệnh gọi để xây dựng không khớp thì phương thức thay thế được gọi (thông qua tra cứu chức năng ngầm) để xây dựng trực tiếp đối tượng. Phương pháp đầu dưới đây gọi phương thức construct() của bộ cấp phát, phía dưới mới là đối tượng trực tiếp:

alloc_traits.h: 250-61

template<typename _Tp, typename... _Args> 
static typename 
    enable_if<__construct_helper<_Tp, _Args...>::value, void>::type 
    _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 
{ __a.construct(__p, std::forward<_Args>(__args)...); } 

template<typename _Tp, typename... _Args> 
static typename 
enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>, 
     is_constructible<_Tp, _Args...>>::value, void>::type 
    _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) 
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } 

Đây là như xa như tôi có thời gian để đi vào thực sự xác định nguồn gốc của các lỗi biên dịch nhưng điều này là đủ cho tôi để đặt cùng một giải pháp đơn giản và hiệu quả cho vấn đề.

Giải pháp ở đây rất đơn giản; boost cần được cập nhật để sử dụng thông số cấp phát C++ 11 mới. Làm điều này thực sự rất đơn giản; trong pool_alloc.hpp thay thế tất cả các trường hợp:

void construct(const pointer ptr, const value_type & t) 
{ new (ptr) T(t); } 

với

template <typename... Args> 
void construct(const pointer ptr, Args&&... args) 
{ 
    new (ptr) T(std::forward<Args>(args)...); 
} 

Nó có vẻ như đây là một lỗi với tăng không cập nhật mã của họ cho C++ 11 hỗ trợ nhưng thực tế là g ++ 5.0 (mà tôi xác nhận) biên dịch mà không có vấn đề ngụ ý rằng việc thêm hỗ trợ này là không bắt buộc trong tương lai. Có thể là std::allocate_shared được dự định tương thích ngược với giao diện cấp phát cũ và lỗi sự cố và biên dịch trên 4.7, 4.8 và 4.9 là hỗ trợ bị hỏng. Tôi sẽ đăng một vé trên trình theo dõi lỗi tăng và xem những gì họ nghĩ rằng thỏa thuận là: boost trac ticket

2

Vì đây có vẻ là vấn đề (?) Với libstdC++, bạn có thể sử dụng hàm tương đương với hàm thư viện chuẩn thay vì boost::allocate_shared. Bao gồm <boost/make_shared.hpp>. Dưới đây là Coliru demo hiển thị bốn phiên bản GCC khác nhau để biên dịch tiền phạt. Như tôi đã đề cập trong các ý kiến, std::allocate_shared làm việc với một xây dựng thân của GCC và với libC++. Tôi không thể tìm thấy báo cáo lỗi hiện có liên quan đến vấn đề này nhưng bạn có thể gửi một báo cáo cho GCC hoặc cho Boost.

+0

Xin chào, tôi đã xem xét tại 'boost :: allocate_shared' và vấn đề là tôi cần' std :: shared_ptr' ra ngoài thay vì tăng tương đương. Tiêu đề của câu hỏi của tôi có phần gây hiểu nhầm, vì vậy tôi sẽ làm rõ; Tôi cần để có thể sử dụng 'std :: allocate_shared' với các cấp phát hồ bơi tăng cường được chỉ định như phương pháp phân bổ. – radman

Các vấn đề liên quan