Date: Wed, 22 Jun 2022 19:58:52 -0400
On Tue, Jun 21, 2022 at 7:23 AM Stephan Bergmann via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> What motivated me to ask this question is the discussion starting in the
> comments at <https://reviews.llvm.org/D127593#3596601> "[clang] Fix
> trivially copyable for copy constructor and copy assignment operator":
>
> Consider
> > struct S1 {};
> > struct S2: S1 {
> > S2(S2 &) = delete;
> > };
> with a deleted copy constructor for S2.
>
> For default constructors and for destructors, the respective definitions
> of triviality are worded in such a way that it apparently makes no
> difference whether or not the given con-/destructor is deleted:
>
> [class.default.ctor]/3:
> > A default constructor is trivial if it is not user-provided and if:
> > — its class has no virtual functions (11.7.2) and no virtual base
> > classes (11.7.1), and
> > — no non-static data member of its class has a default member
> > initializer (11.4), and
> > — all the direct base classes of its class have trivial default
> > constructors, and
> > — for all the non-static data members of its class that are of class
> > type (or array thereof), each such class has a trivial default
> > constructor.
> > Otherwise, the default constructor is non-trivial.
>
> [class.dtor]/8:
> > A destructor is trivial if it is not user-provided and if:
> > — the destructor is not virtual,
> > — all of the direct base classes of its class have trivial destructors,
> > and
> > — for all of the non-static data members of its class that are of class
> > type (or array thereof), each such class has a trivial destructor.
> > Otherwise, the destructor is non-trivial.
>
> But for copy/move constructors and for copy/move assignment operators
> (for which I use the collective term "copy/move operation" here) the
> situation appears to be less clear:
>
> [class.copy.ctor]/11:
> > A copy/move constructor for class X is trivial if it is not
> > user-provided and if:
> > — class X has no virtual functions (11.7.2) and no virtual base classes
> > (11.7.1), and
> > — the constructor selected to copy/move each direct base class subobject
> > is trivial, and
> > — for each non-static data member of X that is of class type (or array
> > thereof), the constructor selected to copy/move that member is trivial;
> > otherwise the copy/move constructor is non-trivial.
>
> [class.copy.assign]/9:
> > A copy/move assignment operator for class X is trivial if it is not
> > user-provided and if:
> > — class X has no virtual functions (11.7.2) and no virtual base classes
> > (11.7.1), and
> > — the assignment operator selected to copy/move each direct base class
> > subobject is trivial, and
> > — for each non-static data member of X that is of class type (or array
> > thereof), the assignment operator selected to copy/move that member is
> > trivial;
> > otherwise the copy/move assignment operator is non-trivial.
>
> Both of the above definitions of triviality delegate to something that
> is "selected to copy/move" certain subobjects. But if the copy/move
> operation is deleted, nothing actually gets selected. That IMO gives
> rise to two potential interpretations: On the one hand, as nothing gets
> selected, it is irrelevant whether what would be selected if the
> copy/move operation were not deleted is trivial (and thus the deleted
> copy constructor of S2 is trivial). On the other hand, as nothing gets
> selected, the requirement that what gets selected is trivial is not met
> (and thus the deleted copy constructor of S2 is non-trivial, as no
> trivial constructor is selected to copy the S1 base class subobject).
>
> (Not sure whether this question makes a practical difference for the
> standard though, as qualification of (non-)triviality of such copy/move
> operations appears to generally by accompanied by some non-deletedness
> qualification.)
>
In core issue 1928, CWG decided that "Any cases in which the triviality of
a deleted function is observable should be amended to remove that
dependency."
You can choose to think that they are trivial or nontrivial according to
which argument you find more compelling, but there really is no answer and
that is intentional.
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
std-discussion_at_[hidden]> wrote:
> What motivated me to ask this question is the discussion starting in the
> comments at <https://reviews.llvm.org/D127593#3596601> "[clang] Fix
> trivially copyable for copy constructor and copy assignment operator":
>
> Consider
> > struct S1 {};
> > struct S2: S1 {
> > S2(S2 &) = delete;
> > };
> with a deleted copy constructor for S2.
>
> For default constructors and for destructors, the respective definitions
> of triviality are worded in such a way that it apparently makes no
> difference whether or not the given con-/destructor is deleted:
>
> [class.default.ctor]/3:
> > A default constructor is trivial if it is not user-provided and if:
> > — its class has no virtual functions (11.7.2) and no virtual base
> > classes (11.7.1), and
> > — no non-static data member of its class has a default member
> > initializer (11.4), and
> > — all the direct base classes of its class have trivial default
> > constructors, and
> > — for all the non-static data members of its class that are of class
> > type (or array thereof), each such class has a trivial default
> > constructor.
> > Otherwise, the default constructor is non-trivial.
>
> [class.dtor]/8:
> > A destructor is trivial if it is not user-provided and if:
> > — the destructor is not virtual,
> > — all of the direct base classes of its class have trivial destructors,
> > and
> > — for all of the non-static data members of its class that are of class
> > type (or array thereof), each such class has a trivial destructor.
> > Otherwise, the destructor is non-trivial.
>
> But for copy/move constructors and for copy/move assignment operators
> (for which I use the collective term "copy/move operation" here) the
> situation appears to be less clear:
>
> [class.copy.ctor]/11:
> > A copy/move constructor for class X is trivial if it is not
> > user-provided and if:
> > — class X has no virtual functions (11.7.2) and no virtual base classes
> > (11.7.1), and
> > — the constructor selected to copy/move each direct base class subobject
> > is trivial, and
> > — for each non-static data member of X that is of class type (or array
> > thereof), the constructor selected to copy/move that member is trivial;
> > otherwise the copy/move constructor is non-trivial.
>
> [class.copy.assign]/9:
> > A copy/move assignment operator for class X is trivial if it is not
> > user-provided and if:
> > — class X has no virtual functions (11.7.2) and no virtual base classes
> > (11.7.1), and
> > — the assignment operator selected to copy/move each direct base class
> > subobject is trivial, and
> > — for each non-static data member of X that is of class type (or array
> > thereof), the assignment operator selected to copy/move that member is
> > trivial;
> > otherwise the copy/move assignment operator is non-trivial.
>
> Both of the above definitions of triviality delegate to something that
> is "selected to copy/move" certain subobjects. But if the copy/move
> operation is deleted, nothing actually gets selected. That IMO gives
> rise to two potential interpretations: On the one hand, as nothing gets
> selected, it is irrelevant whether what would be selected if the
> copy/move operation were not deleted is trivial (and thus the deleted
> copy constructor of S2 is trivial). On the other hand, as nothing gets
> selected, the requirement that what gets selected is trivial is not met
> (and thus the deleted copy constructor of S2 is non-trivial, as no
> trivial constructor is selected to copy the S1 base class subobject).
>
> (Not sure whether this question makes a practical difference for the
> standard though, as qualification of (non-)triviality of such copy/move
> operations appears to generally by accompanied by some non-deletedness
> qualification.)
>
In core issue 1928, CWG decided that "Any cases in which the triviality of
a deleted function is observable should be amended to remove that
dependency."
You can choose to think that they are trivial or nontrivial according to
which argument you find more compelling, but there really is no answer and
that is intentional.
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
-- *Brian Bi*
Received on 2022-06-22 23:59:04