Syntax for Empty Base Optimization

154 views
Skip to first unread message

Avi Kivity

unread,
Nov 26, 2015, 10:34:14 AM11/26/15
to ISO C++ Standard - Future Proposals
Library writers often find themselves wrapping possibly-empty objects in synthetic structs to take advantage of EBO:

  template <typename T, typename Allocator>
  class my_container {
      struct alloc_n_size : Allocator {
          size_t size;
          // ctor etc.
      } _M_alloc_n_size;   // only occupies sizeof(size_t) if is_empty<Allocator>.
      ...
  };

Would it not be more comfortable to supply some syntax for this:

  template <typename T, typename Allocator>
  class my_container {
      size_t _M_size;
      Allocator _M_allocator [[allow_zero_size]];
      ...
  };

the user would be responsible for any problems arising with _M_allocator's address aliasing another object's (for example, by never taking the address of _M_allocator or by never allowing it to be compared to anything).

Nicol Bolas

unread,
Nov 26, 2015, 10:59:16 AM11/26/15
to ISO C++ Standard - Future Proposals

That would be a behavioral difference (the size of `my_container` would be changed). And attributes should never cause a behavioral difference.

Vadim Petrochenkov

unread,
Nov 26, 2015, 11:37:09 AM11/26/15
to ISO C++ Standard - Future Proposals
I often see people mentioning this self-imposed restriction, but it always looks like it does more harm than good.
Suppose that we do want a behavioral difference, like in this case, but we don't want introduce new productions to the grammar, keywords, etc, just some ad hoc syntax.
The we need something else looking and behaving exactly like attributes, but without this restriction on behavioral difference. Why not just reuse attributes?

Nicol Bolas

unread,
Nov 26, 2015, 11:52:41 AM11/26/15
to ISO C++ Standard - Future Proposals
On Thursday, November 26, 2015 at 11:37:09 AM UTC-5, Vadim Petrochenkov wrote:
I often see people mentioning this self-imposed restriction, but it always looks like it does more harm than good.

The standards committee has made it clear by now that making it easy to add keywords is something they don't want to do. Indeed, a proposal for a special feature to make adding keywords easier was shot down because "the difficulty of adding keywords to C++ is a feature".

Using attributes to back-door this restriction is not going to happen.
 
Suppose that we do want a behavioral difference, like in this case, but we don't want introduce new productions to the grammar, keywords, etc, just some ad hoc syntax.

Why don't we want some actual syntax here? Why is an "ad hoc" solution better than a real one?

And more importantly, why should the syntax be on the use of the type rather than on the type itself? That is, why not just have types that, when used as member subobjects, take up no space?

Vadim Petrochenkov

unread,
Nov 26, 2015, 12:02:02 PM11/26/15
to ISO C++ Standard - Future Proposals
>Why don't we want some actual syntax here? Why is an "ad hoc" solution better than a real one?

I explained why, to avoid new extending the language grammar and reuse existing attribute grammar instead.
Many languages do this to introduce niche features, not important enough to deserve a full blown piece of syntax in the core language, many pre-ISO attributes provided by C++ compilers do this as well.

Giovanni Piero Deretta

unread,
Nov 26, 2015, 12:20:37 PM11/26/15
to ISO C++ Standard - Future Proposals
On Thursday, November 26, 2015 at 4:52:41 PM UTC, Nicol Bolas wrote:
On Thursday, November 26, 2015 at 11:37:09 AM UTC-5, Vadim Petrochenkov wrote:
I often see people mentioning this self-imposed restriction, but it always looks like it does more harm than good.

The standards committee has made it clear by now that making it easy to add keywords is something they don't want to do. Indeed, a proposal for a special feature to make adding keywords easier was shot down because "the difficulty of adding keywords to C++ is a feature".

Using attributes to back-door this restriction is not going to happen.
 
Suppose that we do want a behavioral difference, like in this case, but we don't want introduce new productions to the grammar, keywords, etc, just some ad hoc syntax.

Why don't we want some actual syntax here? Why is an "ad hoc" solution better than a real one?

It seems a perfect use of attributes to me. The feature is niche enough not to really warrant its own syntax or keyword and has a very minor effect on the program.

The "no behaviour change" restriction get repeated many times, but it is hardly respected ([[noreturn]], [[carries_dependency]]); The rule that seems to be followed is that a program stripped of all (or some) attributes is still a valid program.
 

And more importantly, why should the syntax be on the use of the type rather than on the type itself? That is, why not just have types that, when used as member subobjects, take up no space?

Because often the type is a template parameter (a function object, an allocator) and the library can't assume it has been correctly marked but might still want to take advantage of the optimization. Of course it should also be possible to tag a type.

-- gpd

 

Nicol Bolas

unread,
Nov 26, 2015, 1:07:20 PM11/26/15
to ISO C++ Standard - Future Proposals
On Thursday, November 26, 2015 at 12:20:37 PM UTC-5, Giovanni Piero Deretta wrote:
On Thursday, November 26, 2015 at 4:52:41 PM UTC, Nicol Bolas wrote:
On Thursday, November 26, 2015 at 11:37:09 AM UTC-5, Vadim Petrochenkov wrote:
I often see people mentioning this self-imposed restriction, but it always looks like it does more harm than good.

The standards committee has made it clear by now that making it easy to add keywords is something they don't want to do. Indeed, a proposal for a special feature to make adding keywords easier was shot down because "the difficulty of adding keywords to C++ is a feature".

Using attributes to back-door this restriction is not going to happen.
 
Suppose that we do want a behavioral difference, like in this case, but we don't want introduce new productions to the grammar, keywords, etc, just some ad hoc syntax.

Why don't we want some actual syntax here? Why is an "ad hoc" solution better than a real one?

It seems a perfect use of attributes to me. The feature is niche enough not to really warrant its own syntax or keyword and has a very minor effect on the program.

How "niche" a feature is is not a reason to make something an attribute.

The "no behaviour change" restriction get repeated many times, but it is hardly respected ([[noreturn]], [[carries_dependency]]); The rule that seems to be followed is that a program stripped of all (or some) attributes is still a valid program.

OK, let's use that reasoning instead. A program should still be valid if all of the attributes are stripped out.

Consider this:

template <typename T>
 
class test {
      size_t size
;
      T
internal [[allow_zero_size]];
 
};

struct empty_t {};

static_assert(sizeof(size_t) == sizeof(test<empty_t>), "Is the attribute set?");

If we had derived `test` from `T` instead of using the attribute, then `test<empty_t>` would be required to be the same size as `size_t`. The rules of standard layout require than, and therefore you can depend on it and even static_assert on it.

With your attribute, if you pass an empty_t, again, you want the standard to require the same behavior: that `internal` take up no space. Therefore, you can `static_assert` on it and everything's fine.

Until you take out the attribute. Then the program becomes invalid, since the static_assert now fires.

Therefore, by your own definition, this is not an appropriate tool for an attribute.


And more importantly, why should the syntax be on the use of the type rather than on the type itself? That is, why not just have types that, when used as member subobjects, take up no space?

Because often the type is a template parameter (a function object, an allocator) and the library can't assume it has been correctly marked but might still want to take advantage of the optimization. Of course it should also be possible to tag a type.

Tagging a type with such an attribute is not only observable behavior (as shown above), it also implies various compile-time checks. Namely, that the type really is empty: it has no NSDMs that aren't themselves empty, no virtual base classes, and no base classes that aren't themselves empty. These are also things attributes should never impose.

Matthew Woehlke

unread,
Nov 26, 2015, 1:54:20 PM11/26/15
to std-pr...@isocpp.org
It seems like the stateless classes proposal¹ would cover this better,
would it not?

http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/22117)

--
Matthew

Nicol Bolas

unread,
Nov 26, 2015, 3:54:58 PM11/26/15
to ISO C++ Standard - Future Proposals, mwoehlk...@gmail.com

To be fair, what he's wanting is slightly different (though it might be worth adding to that proposal). He's saying that a particular variable declaration can be optimized into being stateless if the type happens to be empty by the usual C++ rules (if the type is not empty, then the usual rules apply). This way, the writer of that type does not have to use explicit syntax in order for users to gain the optimization. And therefore, people don't have to derived from possibly empty types in order to get empty optimization.

Nicol Bolas

unread,
Nov 26, 2015, 4:27:21 PM11/26/15
to ISO C++ Standard - Future Proposals
On Thursday, November 26, 2015 at 12:02:02 PM UTC-5, Vadim Petrochenkov wrote:
>Why don't we want some actual syntax here? Why is an "ad hoc" solution better than a real one?

I explained why, to avoid new extending the language grammar and reuse existing attribute grammar instead.

OK, fair enough. Here's a better question.

Can you give a reason that the standards committee has not already heard and rejected several times over? Can you give a reason that would satisfy Herb Sutter?

Many languages do this to introduce niche features, not important enough to deserve a full blown piece of syntax in the core language,

Can you give me some examples these "many languages" that use attributes for syntactic constructs? I'm hardly an expert in numerous languages, so I'm not contesting your statement.

But the only one I know of that makes extensive use of attributes (or syntax like attributes) is C#. And those are primarily for tagging C# constructs with arbitrary data that can be fetched via reflection.
 
many pre-ISO attributes provided by C++ compilers do this as well.

Sure they do. Compilers had ways to set the alignment of types and various other things. But notice that, when it came time to standardize this functionality, they became keywords. When those proposals were initially made, they did indeed use attribute syntax. But various people on the committee made them actual keywords, because they wanted attributes to be reserved for things that compilers could ignore.

When it comes time to standardize features, actual features go into the language, not into attributes.

Andrew Tomazos

unread,
Nov 26, 2015, 8:27:07 PM11/26/15
to std-pr...@isocpp.org
On Thu, Nov 26, 2015 at 10:27 PM, Nicol Bolas <jmck...@gmail.com> wrote:
On Thursday, November 26, 2015 at 12:02:02 PM UTC-5, Vadim Petrochenkov wrote:
>Why don't we want some actual syntax here? Why is an "ad hoc" solution better than a real one?

I explained why, to avoid new extending the language grammar and reuse existing attribute grammar instead.

OK, fair enough. Here's a better question.

Can you give a reason that the standards committee has not already heard and rejected several times over? Can you give a reason that would satisfy Herb Sutter?

Many languages do this to introduce niche features, not important enough to deserve a full blown piece of syntax in the core language,

Can you give me some examples these "many languages" that use attributes for syntactic constructs? I'm hardly an expert in numerous languages, so I'm not contesting your statement.

But the only one I know of that makes extensive use of attributes (or syntax like attributes) is C#. And those are primarily for tagging C# constructs with arbitrary data that can be fetched via reflection.
 
many pre-ISO attributes provided by C++ compilers do this as well.

Sure they do. Compilers had ways to set the alignment of types and various other things. But notice that, when it came time to standardize this functionality, they became keywords. When those proposals were initially made, they did indeed use attribute syntax. But various people on the committee made them actual keywords, because they wanted attributes to be reserved for things that compilers could ignore.

When it comes time to standardize features, actual features go into the language, not into attributes.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Thiago Macieira

unread,
Nov 27, 2015, 2:17:03 AM11/27/15
to std-pr...@isocpp.org
On Thursday 26 November 2015 09:02:02 Vadim Petrochenkov wrote:
> >Why don't we want some actual syntax here? Why is an "ad hoc" solution
>
> better than a real one?
>
> I explained why, to avoid new extending the language grammar and reuse
> existing attribute grammar instead.

Avoiding extending the language is not a reason for avoiding extending the
language.

Your proposal to use attributes is the "how". The question was "why"
attributes, instead of a non-attribute keyword?

> Many languages do this to introduce niche features, not important enough to
> deserve a full blown piece of syntax in the core language, many pre-ISO
> attributes provided by C++ compilers do this as well.

And the committee explicitly changed that. Take the example of forcing
alignment: prior to C++11, all compilers had it in some form of attribute. For
GCC and compatible compilers, it is __attribute__((aligned(n))).

C++11 added a keyword for it: alignas(n)

And you may note that this keyword is defined in the standard in the same
section as attributes. It just doesn't use the [[]] syntax.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358

Reply all
Reply to author
Forward
0 new messages