Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Feb 2016 16:50:33 +0100
From:      Dimitry Andric <dim@FreeBSD.org>
To:        Willem Jan Withagen <wjw@digiware.nl>
Cc:        FreeBSD Toolchain <freebsd-toolchain@freebsd.org>
Subject:   Re: Ceph compilation on inclusion of /usr/include/c++/v1/deque
Message-ID:  <FF4EAE21-82C5-4105-8AED-993C6F3B2F7B@FreeBSD.org>
In-Reply-To: <56C88191.7030801@digiware.nl>
References:  <56C88191.7030801@digiware.nl>

next in thread | previous in thread | raw e-mail | index | archive | help

--Apple-Mail=_A00D131F-74B9-4436-8A20-62AA7152D61F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

On 20 Feb 2016, at 16:09, Willem Jan Withagen <wjw@digiware.nl> wrote:
>=20
> 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
>=20
> 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 =3D 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 =3D 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 =3D foo; _Alloc =3D std::allocator<foo>; std::size_t =3D =
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 =3D foo; =
_Alloc =3D std::allocator<foo>]'
    /usr/local/lib/gcc6/include/c++/bits/stl_deque.h:884:23:   required =
from 'std::deque<_Tp, _Alloc>::deque() [with _Tp =3D foo; _Alloc =3D =
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 =3D (__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 =3D 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?

-Dimitry


--Apple-Mail=_A00D131F-74B9-4436-8A20-62AA7152D61F
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename=signature.asc
Content-Type: application/pgp-signature;
	name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail

-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.29

iEYEARECAAYFAlbIi1MACgkQsF6jCi4glqO2MQCeKem6LeqXxcXeI87HovaOD56p
+M0An2Va/AzGJ1XYKMpmb6bhdks5/55X
=srsF
-----END PGP SIGNATURE-----

--Apple-Mail=_A00D131F-74B9-4436-8A20-62AA7152D61F--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FF4EAE21-82C5-4105-8AED-993C6F3B2F7B>