public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* empty base optimization vs. final class or virtual base
@ 2012-06-07 20:01 Kalle Olavi Niemitalo
  2012-06-07 20:21 ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Kalle Olavi Niemitalo @ 2012-06-07 20:01 UTC (permalink / raw)
  To: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1528 bytes --]

In GCC 4.7.0, std::vector<_Tp, _Alloc> internally uses
std::_Vector_base<_Tp, _Alloc>::_Vector_impl, which derives from
the allocator class (found via std::allocator_traits).  If the
allocator class is final (in C++11) or has a virtual base that
lacks a default constructor, then compilation will fail.

The GCC implementation of std::tuple uses the empty base
optimization only "for empty, non-final types", so it does not
have this problem.

* Should I file a bug for adding similar checks in std::vector?
  It seems unlikely that anyone would use such weird allocators
  in real programs, especially as std::scoped_allocator_adaptor
  is explicitly specified to derive from the user's allocator.

* In my own templates intended to be portable, what is a good way
  to apply the empty base optimization only if it is safe?  It
  seems to require an awful lot of boilerplate code, and I don't
  think __is_final is standard.

Here is a sample that demonstrates the errors from giving
std::vector an allocator with a virtual base.

#include <memory>
#include <vector>

struct vbase
{
  explicit vbase(int) {}
};

template <typename Value>
struct nasty: virtual vbase, std::allocator<Value>
{
  template <typename U> struct rebind { typedef nasty<U> other; };

  nasty(): vbase(0), std::allocator<Value>() {}
  nasty(const nasty& other): vbase(0), std::allocator<Value>(other) {}
  template <typename U> nasty(const nasty<U>& other): vbase(0), std::allocator<Value>(other) {}
  ~nasty() {}
};

std::vector<int, nasty<int> > bob;

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: empty base optimization vs. final class or virtual base
  2012-06-07 20:01 empty base optimization vs. final class or virtual base Kalle Olavi Niemitalo
@ 2012-06-07 20:21 ` Jonathan Wakely
  2012-06-07 20:40   ` Kalle Olavi Niemitalo
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2012-06-07 20:21 UTC (permalink / raw)
  To: Kalle Olavi Niemitalo; +Cc: gcc-help

On 7 June 2012 21:05, Kalle Olavi Niemitalo wrote:
> In GCC 4.7.0, std::vector<_Tp, _Alloc> internally uses
> std::_Vector_base<_Tp, _Alloc>::_Vector_impl, which derives from
> the allocator class (found via std::allocator_traits).  If the
> allocator class is final (in C++11) or has a virtual base that
> lacks a default constructor, then compilation will fail.
>
> The GCC implementation of std::tuple uses the empty base
> optimization only "for empty, non-final types", so it does not
> have this problem.
>
> * Should I file a bug for adding similar checks in std::vector?

No thanks, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51365 is still
open until I fix it for final allocators in containers.

>  It seems unlikely that anyone would use such weird allocators
>  in real programs, especially as std::scoped_allocator_adaptor
>  is explicitly specified to derive from the user's allocator.

That's why it's not a high priority for me to fix it.

> * In my own templates intended to be portable, what is a good way
>  to apply the empty base optimization only if it is safe?  It
>  seems to require an awful lot of boilerplate code, and I don't
>  think __is_final is standard.

If you have at least two members, one or more of which might be empty,
then store them in a std::tuple to automatically use the EBO if
possible.

e.g. std::unique_ptr has to store a pointer and a possibly empty
deleter, so it has a member of type std::tuple<pointer, D>. If D is
empty and non-final then the tuple is the same size as the pointer.
std::tuple knows how to check for final classes and handle them
appropriately.

If it wouldn't break the ABI then I would use std::tuple in all the
containers to use the EBO for allocators.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: empty base optimization vs. final class or virtual base
  2012-06-07 20:21 ` Jonathan Wakely
@ 2012-06-07 20:40   ` Kalle Olavi Niemitalo
  0 siblings, 0 replies; 3+ messages in thread
From: Kalle Olavi Niemitalo @ 2012-06-07 20:40 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 228 bytes --]

Jonathan Wakely <jwakely.gcc@gmail.com> writes:

> If you have at least two members, one or more of which might be empty,
> then store them in a std::tuple to automatically use the EBO if
> possible.

Thank you for this advice.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-06-07 20:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-07 20:01 empty base optimization vs. final class or virtual base Kalle Olavi Niemitalo
2012-06-07 20:21 ` Jonathan Wakely
2012-06-07 20:40   ` Kalle Olavi Niemitalo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).