Ceph compilation on inclusion of /usr/include/c++/v1/deque
Willem Jan Withagen
wjw at digiware.nl
Sun Feb 21 10:42:47 UTC 2016
On 20-2-2016 20:47, Willem Jan Withagen wrote:
> On 20-2-2016 16:50, Dimitry Andric wrote:
>> On 20 Feb 2016, at 16:09, Willem Jan Withagen <wjw at digiware.nl> wrote:
>>>
>>> I'm trying to build a port of Ceph for FreeBSD, which is sort of trying
>>> to shoot at a tank with a watergun.... :)
>>
>> This is very nice, it would be good to have Ceph on FreeBSD. Note that
>> if you have problems with porting, usually the freebsd-ports mailing
>> list is a better audience.
>>
>>
>>> I you want to reproduce it is rather labourious, but not all that complex:
>>> git clone https://github.com/wjwithagen/ceph.git
>>> cd ceph
>>> git checkout wip-wjw-freebsd-tests
>>> ./do_freebsd.sh
>>>
>>> And wait for the error to appear.
>> ...
>>> /usr/include/c++/v1/deque:912:49: error: invalid application of 'sizeof'
>>> to an incomplete type 'value_type' (aka 'RGWPeriod')
>>> static const difference_type __block_size = sizeof(value_type) < 256
>>> ? 4096 / sizeof(value_type) : 16;
>>> ^~~~~~~~~~~~~~~~~~
>>> /usr/include/c++/v1/deque:1159:15: note: in instantiation of template
>>> class 'std::__1::__deque_base<RGWPeriod,
>>> std::__1::allocator<RGWPeriod> >' requested here
>>> : private __deque_base<_Tp, _Allocator>
>>> ^
>>> rgw/rgw_period_history.h:26:27: note: in instantiation of template class
>>> 'std::__1::deque<RGWPeriod, std::__1::allocator<RGWPeriod>
>>>> ' requested here
>>> std::deque<RGWPeriod> periods;
>>> ^
>>> rgw/rgw_period_history.h:16:7: note: forward declaration of 'RGWPeriod'
>>> class RGWPeriod;
>>> ^
>>
>> Without having to build anything, I see the problem already. :) The
>> error message is unfortunately rather confusing, but the gist of it is
>> that the implementation of std::deque<> requires a complete type.
>>
>> Which means that you cannot do this:
>>
>> #include <deque>
>> class foo;
>> std::deque<foo> bar;
>>
>> Compiling this example with clang and libc++ will result in (not all
>> errors shown, no need to):
>>
>> In file included from deque-test.cpp:1:
>> /usr/include/c++/v1/deque:912:49: error: invalid application of 'sizeof' to an incomplete type 'value_type' (aka 'foo')
>> static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
>> ^~~~~~~~~~~~~~~~~~
>> /usr/include/c++/v1/deque:1159:15: note: in instantiation of template class 'std::__1::__deque_base<foo, std::__1::allocator<foo> >' requested here
>> : private __deque_base<_Tp, _Allocator>
>> ^
>> deque-test.cpp:3:17: note: in instantiation of template class 'std::__1::deque<foo, std::__1::allocator<foo> >' requested here
>> std::deque<foo> bar;
>> ^
>> deque-test.cpp:2:7: note: forward declaration of 'foo'
>> class foo;
>> ^
>>
>> Similarly, compiling the example with g++ and libstdc++ (6.0.0 from
>> ports) results in:
>>
>> In file included from /usr/local/lib/gcc6/include/c++/deque:64:0,
>> from deque-test.cpp:1:
>> /usr/local/lib/gcc6/include/c++/bits/stl_deque.h: In instantiation of 'void std::_Deque_base<_Tp, _Alloc>::_M_initialize_map(std::size_t) [with _Tp = foo; _Alloc = std::allocator<foo>; std::size_t = unsigned int]':
>> /usr/local/lib/gcc6/include/c++/bits/stl_deque.h:490:26: required from 'std::_Deque_base<_Tp, _Alloc>::_Deque_base() [with _Tp = foo; _Alloc = std::allocator<foo>]'
>> /usr/local/lib/gcc6/include/c++/bits/stl_deque.h:884:23: required from 'std::deque<_Tp, _Alloc>::deque() [with _Tp = foo; _Alloc = std::allocator<foo>]'
>> deque-test.cpp:3:17: required from here
>> /usr/local/lib/gcc6/include/c++/bits/stl_deque.h:682:74: error: invalid application of 'sizeof' to incomplete type 'foo'
>> const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp))
>> ^
>> /usr/local/lib/gcc6/include/c++/bits/stl_deque.h:713:31: error: invalid application of 'sizeof' to incomplete type 'foo'
>> % __deque_buf_size(sizeof(_Tp)));
>> ^
>>
>> Looking at rgw_period_history.h, it is indeed using an incomplete type:
>>
>> #include <deque>
>> #include <mutex>
>> #include <system_error>
>> #include <boost/intrusive/avl_set.hpp>
>> #include "include/assert.h"
>> #include "include/types.h"
>>
>> namespace bi = boost::intrusive;
>>
>> class RGWPeriod;
>>
>> /**
>> * RGWPeriodHistory tracks the relative history of all inserted periods,
>> * coordinates the pulling of missing intermediate periods, and provides a
>> * Cursor object for traversing through the connected history.
>> */
>> class RGWPeriodHistory final {
>> /// an ordered history of consecutive periods
>> struct History : public bi::avl_set_base_hook<> {
>> std::deque<RGWPeriod> periods;
>>
>> E.g at this point, all the compiler has is a forward declaration of
>> RGWPeriod. If this even compiles on Linux, I am unsure how it manages
>> to do so. :-) Maybe the Linux build pulls in some other header first,
>> getting the full definition of RGWPeriod somehow?
>>
>> In any case, the easiest fix is probably to switch around the inclusions
>> of the headers in rgw_period_history.cc, e.g. changing:
>>
>> #include "rgw_period_history.h"
>> #include "rgw_rados.h"
>>
>> to:
>>
>> #include "rgw_rados.h"
>> #include "rgw_period_history.h"
>>
>> Since rgw_rados.h contains the full definition of RGWPeriod, the forward
>> declaration on line 16 of rgw_period_history.h can then be deleted.
>>
>> Alternatively, include rgw_rados.h directly in rgw_period_history.h,
>> which is what I would do. I am unsure how Ceph upstream thinks about
>> that, though. Maybe you can check with them?
>
> Hi Dimitry,
>
> Thanx for all the advise.
> It is going to take some time to absorbe all. :)
>
> I've got a FreeBSD pull running, and on and off I'm commented by other
> committers as to how or why... You've given enough text to actually put
> in the commit message. And we'll find out how they feel about it.
>
> As to running this by the ports list, I have not really seen any this
> type of problem passing by there. Next to that I expected it more to be
> GCC <> Clang because every commit is run through Jenkins compilation and
> testing, and it would be noticed there.
There were some more loop dependancies which required forward
declaration and alter inclusion of include files.
But in the end I got it to compile again.
So thanx for the help.
--WjW
More information about the freebsd-toolchain
mailing list