Thank you very much Jens, your feedback is most helpful!I've fixed the paper accordingly.
Just to clarify - for the purposes of SG22 - the target of the paper is:
- To allow alignof(obj)
- To state that for expression t, which is an object of type T, alignof(t) equals (as it is in C):
- The value x stated in 'alignas(x) T t;' if exists, or
- The value of 'alignof(decltype(t))'
- (Continue) not allowing `alignas(y) T t` when y < alignof(T) (as it is in C).
When 'obj' is limited to a complete object (this approach already exists in the C++ standard: [basic.align/2]) Wording still needs extra work, as Jens correctly specified.
Thanks,
Inbal Levi
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Few comments / questions:
> What exactly is unspecified here?
Sorry, You're right. I wrote that in the paper long ago, but when I answered the mail I got confused and gave examples for `alignas()`. I've changed the examples to include `alignof()` (in the paper as well):
- [basic.align/2] contains `alignof(std::max_align_t)`
- [dcl.align/3] contains `alignas(alignof( type-id ))`
- [mem.poly.allocator.mem/8.2] contains `alignof(T)`
Those are considered expressions, IIUC?
> {expr.alignof] needs a change to the alignof grammar to allow id-expression
and class member access expressions (apparently, you want to restrict to these;
fine).
The part about data class members was actually donated by David, but I'm willing to get inputs. I've tried adding wording accordingly (may need additional corrections).
> With alignof(id-expression), there is no type as the operand, but an id-expression.
What's the result here?> What if the id-expression designates a bit-field?
Good points. Should we narrow down to just allowing alignof(obj) (or the equivalent to obj in the standard) or something like what C has for alignas?"_Alignas can't be used in the declaration of a typedef, bit-field, function, function parameter, or an object declared with the register specifier."
>> "the alignment of an entity"
> Do you mean object here?
Yes, thank you. fixed.
The following comment relates to issue [4.2] in the paper, which I moved to Appendix A because I no longer suggest a change for it:
>> "The alignment of an object in C is resolved to the strictest amongst its members"
>> While I believe such a rule might be reasonable to provide explicitly (at least for standard-layout or trivial types), I fail to find it in WG14 N2573 6.7.5 "The combined effect of all alignment specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would otherwise be required for the type of the object or member being declared."
> It does; see [dcl.align] p5.
I failed to specify my intention here - it's very subtle, but there's a difference between C++'s phrasing and C's phrasing:
C++'s phrasing:
The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would
be required for the entity being declared if all alignment-specifiers appertaining to that entity were omitted.
C's phrasing:
The combined effect of all alignment specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would
otherwise be required for the type of the object or member being declared.
My point was that the "or member" that appears in C's phrasing is the thing we're missing, but since then I've come to realize the intention is that the object is being declared as a member, and not that it is restricted by its members.
In any case, this is the point of [4.2], but I did not suggest any wording for it in the paper.
To emphasize:
let's assume A is the alignment of type T, and X is the alignment of t, which is an object of type T:
alignas(64) T{...} ---> A = 64 ---> (by the rule you've correctly quoted: (Rule I)) ---> X >= 64 ---> (by the rule we have in C++: (Rule II)) ----> "alignas(16) T t;" will fail
(Rule I): "An alignof expression yields the alignment requirement of its operand type."
(Rule II): "The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers appertaining to that entity were omitted."
But if:
T{
alignas(64) int i;
alignas(16) int j;
};
---> (?) ---> A = 64 ---> ...
(?) Should we add something for this? I have seen different behaviours regarding how the member's alignment affects the object's alignment, which may suggest we don't specify it well enough, even with (Rule II) + (Rule I). But again, this is not the major point of the Paper, and I've removed the wording to try and deal with it.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~