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:
  1. To allow alignof(obj)
  2. To state that for expression t, which is an object of type T, alignof(t) equals (as it is in C):
    1. The value x stated in 'alignas(x) T t;' if exists, or
    2. The value of 'alignof(decltype(t))'
  3. (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.

Updated revision is here, I've also rebased on the latest C, C++ standards (both released in October 2021): https://isocpp.org/files/papers/P2152R1.pdf


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.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



On Sun, 3 Oct 2021 at 17:09, Jens Maurer <Jens.Maurer@gmx.net> wrote:
On 01/10/2021 12.37, Inbal Levi wrote:
>> I can't find any in the standard. Please list those
> I ment 'alignas(exp)' for example - 'alignas(obj)' even though it's undefined. I added examples to the paper (E.g. under [expr.const] section 10, N4892)

It is defined.  "alignas(constant-expression)"; see [dcl.align].

And alignas(T...) is also defined there.

What exactly is unspecified here?

>> "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
> This appears on reference [6] in the paper. It's under '6.7.5 Alignment specifier' / section 5 (in N2596 C standard). To my understanding, this results from: "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."
> This does not exist on C++,

It does; see [dcl.align] p5.

>> [expr.alignof] talks about alignof(expr), but doesn't say what it means at all.
> I'll point out that I did avoid specifying the value of alignof(obj) on purpose (just like there is no explicit value specification of alignof(type-id),

That's wrong. We say

"An alignof expression yields the alignment requirement of its operand type."

With alignof(id-expression), there is no type as the operand, but an id-expression.
What's the result here?

"id-expression" needs to be italics and should have a cross-reference.

What if the id-expression designates a bit-field?

>  I refer to it as an issue, it's only mentioned that it cannot be smaller than the alignment value if it was omitted). I also refer in the paper to implementation details and Itanium ABI.

{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).

>> [dcl.align] This wording should move to [basic.align], saying that the alignment requirement of a (trivial? standard-layout?) class type is the strictest alignment of its non-static data members or so.
> The change in [dcl.align] is an attempt to 'fix' the paragraph to be like in C, in order to address the issue brought up in the previous section. I removed this.
[basic.align] The sentence about "object type" should come first,
and then the standard-layout class type thing.

"the alignment of an entity"

Do you mean object here?

> We already have under section [basic.align/1]: "An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier", but I feel comfortable with adding wording as you suggested.

"and equals alignof(decltype(obj));" feels duplicate with [expr.alignof].

Jens