C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] A request for feedback on "P2152: Querying the Alignment of an Object [Aligning Alignment]"

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Tue, 30 Nov 2021 22:13:10 +0100
On 30/11/2021 15.40, Inbal Levi wrote:
> 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 <https://isocpp.org/files/papers/P2152R1.pdf>

"[basic.align/2] contains alignof(expr), [dcl.align/3] contains ‘alignof( type-id )‘"

The latter part is correct and intended, but I'm not seeing any mention
of "alignof(expr)" in basic.align p2. std::max_align_t is a type,
not an expression. Please quote (i.e. copy text) that supports your
claim or remove the bogus claim from your paper.

Section 2:
Using names for linkage purposes seems to be misguided.
Or is there something special about names for linkage
purposes that you want to highlight here?
If you want to show code that compiles with both C and C++,
use "struct U" (etc) when you refer to the struct.

Section 4.1:
"__attribute__(aligned(32)))" is not C.

"However, there are multiple references to functionality derived from allowing ‘alignof(expression)‘."

Not in the standard, as far as I know. If you have counter-examples,
please present them, with specifics. Otherwise, please present
"alignof(expression)" as what it is: a vendor extension.
If you think it's sufficiently useful to be standardized, that's
fine, but "multiple references" is actively misleading in this
regard.

Thus, the latter part of
"As a result, there is inconsistency between different compilers, and within the C++ standard."
is simply factually wrong.

And it's expected that compilers are inconsistent with respect
to vendor extensions (that's what the name implies), so no
surprises there.

"For expression t, which is an object of type T:"

An expression is never an object.
An expression might be an lvalue that designates an object, though.
Note that the dynamic type of the object might differ from its
static type (i.e. the type of the expression), so this needs clarity
what is meant.

"This will affect additional features such as the alignment of a pointer and of a reference."

Why? What's special about pointers here?
References are not objects, so alignment doesn't apply to them anyway.


Section 6:
"Add in [expr.alignof/1] allowing the alignof(id-expression)."The grammar for alignof is in expr.unary.general, not in expr.alignof.


Section 7:
[basic.align] "as well as the hardware type"

We already say that the alignment is implementation-defined, so I think
this is totally superfluous (and possibly misleading, because it might
give the wrong impression that no other factors affect alignment).

[expr.alignof]
The ostensibly unchanged part mentions alignof(id-expression), which doesn't
currently exist in the standard.
Please correctly quote the existing wording and then show the changes
you'd like to have applied.

If you want to allow alignof(id-expression), you should properly formulate
restrictions on the id-expression (e.g. is "alignof(~T)" valid?) and for
all allowed id-expressions, you should clearly say what the result is.

Also, [temp.dep.constexpr] needs to be amended.


Jens



>
> 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_at_[hidden] <mailto:Jens.Maurer_at_[hidden]>> 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
>

Received on 2021-11-30 15:13:16