Implicitly defined constructor deleted due to variant member, N3690/N4140 vs N4659/N4727
My story starts off the same as this person's here:
Unions in C++11: default constructor seems to be deleted
The resolution here (now about three years old) is a bit unsatisfactory, because the "Digging into the standard" that the author did ended up with concluding that the behavior was as described in the standard, but unfortunately the quote is from a Note, and those are supposed to be non-normative (I've been told). Anyways, there's a link to an old bug report on gcc that is claimed to be fixed, and they also claim that the code compiles in clang, however I'm having issues (with the same and similar code). The matter boils down to a whether or not a union-like class with a default initialized variant member should compile whether or not there is another variant member (in the same variant set) that has a non-trivial constructor.
struct X
X() //non-trivial default constructor
;
struct U
union
X x;
int i0; //default member initializer
;
;
U u; //error: default constructor deleted
These failed with -std=c++14
and -std=c++17
on gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
as well as clang version 6.0.0-1ubuntu2
.
There seems to be a history of change in the standard, and so I'll put forth what I've found:
N3690/N4140:
[12.1.4/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union-like class that has a variant member with a non-trivial default constructor
[9.5.2/Unions]...
[Note:
If any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
N4659/N4727:
[15.1.5/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer
[12.3.3/Unions]...
[Note:
Absent default member initializers, if any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
Anyways, it seems like at one point this code should have failed, but it was thought to be conforming and that gcc had a bug, and it was claimed to be fixed, but now it should succeed, and it doesn't compile (I may not have the chronology perfect here, it would be interesting to know the full story; figuring it out is one step further than I'd like to take) but I guess I'm just wondering what is the correct behavior?
c++ g++ language-lawyer unions clang++
add a comment |
My story starts off the same as this person's here:
Unions in C++11: default constructor seems to be deleted
The resolution here (now about three years old) is a bit unsatisfactory, because the "Digging into the standard" that the author did ended up with concluding that the behavior was as described in the standard, but unfortunately the quote is from a Note, and those are supposed to be non-normative (I've been told). Anyways, there's a link to an old bug report on gcc that is claimed to be fixed, and they also claim that the code compiles in clang, however I'm having issues (with the same and similar code). The matter boils down to a whether or not a union-like class with a default initialized variant member should compile whether or not there is another variant member (in the same variant set) that has a non-trivial constructor.
struct X
X() //non-trivial default constructor
;
struct U
union
X x;
int i0; //default member initializer
;
;
U u; //error: default constructor deleted
These failed with -std=c++14
and -std=c++17
on gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
as well as clang version 6.0.0-1ubuntu2
.
There seems to be a history of change in the standard, and so I'll put forth what I've found:
N3690/N4140:
[12.1.4/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union-like class that has a variant member with a non-trivial default constructor
[9.5.2/Unions]...
[Note:
If any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
N4659/N4727:
[15.1.5/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer
[12.3.3/Unions]...
[Note:
Absent default member initializers, if any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
Anyways, it seems like at one point this code should have failed, but it was thought to be conforming and that gcc had a bug, and it was claimed to be fixed, but now it should succeed, and it doesn't compile (I may not have the chronology perfect here, it would be interesting to know the full story; figuring it out is one step further than I'd like to take) but I guess I'm just wondering what is the correct behavior?
c++ g++ language-lawyer unions clang++
1
Notes are indeed non-normative. That's a general principle for ISO standards; works the same in ISO C.
– MSalters
Nov 15 '18 at 0:45
Related Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit default constructor?
– Shafik Yaghmour
Nov 15 '18 at 2:43
add a comment |
My story starts off the same as this person's here:
Unions in C++11: default constructor seems to be deleted
The resolution here (now about three years old) is a bit unsatisfactory, because the "Digging into the standard" that the author did ended up with concluding that the behavior was as described in the standard, but unfortunately the quote is from a Note, and those are supposed to be non-normative (I've been told). Anyways, there's a link to an old bug report on gcc that is claimed to be fixed, and they also claim that the code compiles in clang, however I'm having issues (with the same and similar code). The matter boils down to a whether or not a union-like class with a default initialized variant member should compile whether or not there is another variant member (in the same variant set) that has a non-trivial constructor.
struct X
X() //non-trivial default constructor
;
struct U
union
X x;
int i0; //default member initializer
;
;
U u; //error: default constructor deleted
These failed with -std=c++14
and -std=c++17
on gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
as well as clang version 6.0.0-1ubuntu2
.
There seems to be a history of change in the standard, and so I'll put forth what I've found:
N3690/N4140:
[12.1.4/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union-like class that has a variant member with a non-trivial default constructor
[9.5.2/Unions]...
[Note:
If any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
N4659/N4727:
[15.1.5/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer
[12.3.3/Unions]...
[Note:
Absent default member initializers, if any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
Anyways, it seems like at one point this code should have failed, but it was thought to be conforming and that gcc had a bug, and it was claimed to be fixed, but now it should succeed, and it doesn't compile (I may not have the chronology perfect here, it would be interesting to know the full story; figuring it out is one step further than I'd like to take) but I guess I'm just wondering what is the correct behavior?
c++ g++ language-lawyer unions clang++
My story starts off the same as this person's here:
Unions in C++11: default constructor seems to be deleted
The resolution here (now about three years old) is a bit unsatisfactory, because the "Digging into the standard" that the author did ended up with concluding that the behavior was as described in the standard, but unfortunately the quote is from a Note, and those are supposed to be non-normative (I've been told). Anyways, there's a link to an old bug report on gcc that is claimed to be fixed, and they also claim that the code compiles in clang, however I'm having issues (with the same and similar code). The matter boils down to a whether or not a union-like class with a default initialized variant member should compile whether or not there is another variant member (in the same variant set) that has a non-trivial constructor.
struct X
X() //non-trivial default constructor
;
struct U
union
X x;
int i0; //default member initializer
;
;
U u; //error: default constructor deleted
These failed with -std=c++14
and -std=c++17
on gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
as well as clang version 6.0.0-1ubuntu2
.
There seems to be a history of change in the standard, and so I'll put forth what I've found:
N3690/N4140:
[12.1.4/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union-like class that has a variant member with a non-trivial default constructor
[9.5.2/Unions]...
[Note:
If any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
N4659/N4727:
[15.1.5/Constructors]
...A defaulted default constructor for class X is defined as deleted if:
- X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer
[12.3.3/Unions]...
[Note:
Absent default member initializers, if any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union.
— end note]
Anyways, it seems like at one point this code should have failed, but it was thought to be conforming and that gcc had a bug, and it was claimed to be fixed, but now it should succeed, and it doesn't compile (I may not have the chronology perfect here, it would be interesting to know the full story; figuring it out is one step further than I'd like to take) but I guess I'm just wondering what is the correct behavior?
c++ g++ language-lawyer unions clang++
c++ g++ language-lawyer unions clang++
edited Nov 16 '18 at 1:00
Shafik Yaghmour
126k23327543
126k23327543
asked Nov 15 '18 at 0:15
Nathan ChappellNathan Chappell
1278
1278
1
Notes are indeed non-normative. That's a general principle for ISO standards; works the same in ISO C.
– MSalters
Nov 15 '18 at 0:45
Related Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit default constructor?
– Shafik Yaghmour
Nov 15 '18 at 2:43
add a comment |
1
Notes are indeed non-normative. That's a general principle for ISO standards; works the same in ISO C.
– MSalters
Nov 15 '18 at 0:45
Related Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit default constructor?
– Shafik Yaghmour
Nov 15 '18 at 2:43
1
1
Notes are indeed non-normative. That's a general principle for ISO standards; works the same in ISO C.
– MSalters
Nov 15 '18 at 0:45
Notes are indeed non-normative. That's a general principle for ISO standards; works the same in ISO C.
– MSalters
Nov 15 '18 at 0:45
Related Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit default constructor?
– Shafik Yaghmour
Nov 15 '18 at 2:43
Related Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit default constructor?
– Shafik Yaghmour
Nov 15 '18 at 2:43
add a comment |
1 Answer
1
active
oldest
votes
I believe you are correct, this should be valid code now.
The original wording for the non-normative note that descirbes the old behavior comes from n2544: Unrestricted Unions (Revision 2).
That change you note in the normative section comes from Core defect report 2048: NSDMIs and deleted union default constructors which says:
According to 15.1 [class.ctor] paragraph 4 says,
A defaulted default constructor for class X is defined as deleted if:
X is a union-like class that has a variant member with a non-trivial default constructor,
...
This should make the following example ill-formed:
struct S
S();
;
union U
S s;
u;
because the default constructor of U is deleted. However, both clang
and g++ accept this without error. Should the rule be relaxed for a
union with an NSDMI?
and modified [class.default.ctor]p2 as you referenced from N4659/N4727
. Additionally we can see that the case mentioned in the DR does indeed work for gcc and clang but not for MSVC see it live on godbolt.
This feels like a bug since [class.default.ctor]p2.1 should cover this case and make it will-formed since the member i
has a default member initializer:
X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310690%2fimplicitly-defined-constructor-deleted-due-to-variant-member-n3690-n4140-vs-n46%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I believe you are correct, this should be valid code now.
The original wording for the non-normative note that descirbes the old behavior comes from n2544: Unrestricted Unions (Revision 2).
That change you note in the normative section comes from Core defect report 2048: NSDMIs and deleted union default constructors which says:
According to 15.1 [class.ctor] paragraph 4 says,
A defaulted default constructor for class X is defined as deleted if:
X is a union-like class that has a variant member with a non-trivial default constructor,
...
This should make the following example ill-formed:
struct S
S();
;
union U
S s;
u;
because the default constructor of U is deleted. However, both clang
and g++ accept this without error. Should the rule be relaxed for a
union with an NSDMI?
and modified [class.default.ctor]p2 as you referenced from N4659/N4727
. Additionally we can see that the case mentioned in the DR does indeed work for gcc and clang but not for MSVC see it live on godbolt.
This feels like a bug since [class.default.ctor]p2.1 should cover this case and make it will-formed since the member i
has a default member initializer:
X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,
add a comment |
I believe you are correct, this should be valid code now.
The original wording for the non-normative note that descirbes the old behavior comes from n2544: Unrestricted Unions (Revision 2).
That change you note in the normative section comes from Core defect report 2048: NSDMIs and deleted union default constructors which says:
According to 15.1 [class.ctor] paragraph 4 says,
A defaulted default constructor for class X is defined as deleted if:
X is a union-like class that has a variant member with a non-trivial default constructor,
...
This should make the following example ill-formed:
struct S
S();
;
union U
S s;
u;
because the default constructor of U is deleted. However, both clang
and g++ accept this without error. Should the rule be relaxed for a
union with an NSDMI?
and modified [class.default.ctor]p2 as you referenced from N4659/N4727
. Additionally we can see that the case mentioned in the DR does indeed work for gcc and clang but not for MSVC see it live on godbolt.
This feels like a bug since [class.default.ctor]p2.1 should cover this case and make it will-formed since the member i
has a default member initializer:
X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,
add a comment |
I believe you are correct, this should be valid code now.
The original wording for the non-normative note that descirbes the old behavior comes from n2544: Unrestricted Unions (Revision 2).
That change you note in the normative section comes from Core defect report 2048: NSDMIs and deleted union default constructors which says:
According to 15.1 [class.ctor] paragraph 4 says,
A defaulted default constructor for class X is defined as deleted if:
X is a union-like class that has a variant member with a non-trivial default constructor,
...
This should make the following example ill-formed:
struct S
S();
;
union U
S s;
u;
because the default constructor of U is deleted. However, both clang
and g++ accept this without error. Should the rule be relaxed for a
union with an NSDMI?
and modified [class.default.ctor]p2 as you referenced from N4659/N4727
. Additionally we can see that the case mentioned in the DR does indeed work for gcc and clang but not for MSVC see it live on godbolt.
This feels like a bug since [class.default.ctor]p2.1 should cover this case and make it will-formed since the member i
has a default member initializer:
X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,
I believe you are correct, this should be valid code now.
The original wording for the non-normative note that descirbes the old behavior comes from n2544: Unrestricted Unions (Revision 2).
That change you note in the normative section comes from Core defect report 2048: NSDMIs and deleted union default constructors which says:
According to 15.1 [class.ctor] paragraph 4 says,
A defaulted default constructor for class X is defined as deleted if:
X is a union-like class that has a variant member with a non-trivial default constructor,
...
This should make the following example ill-formed:
struct S
S();
;
union U
S s;
u;
because the default constructor of U is deleted. However, both clang
and g++ accept this without error. Should the rule be relaxed for a
union with an NSDMI?
and modified [class.default.ctor]p2 as you referenced from N4659/N4727
. Additionally we can see that the case mentioned in the DR does indeed work for gcc and clang but not for MSVC see it live on godbolt.
This feels like a bug since [class.default.ctor]p2.1 should cover this case and make it will-formed since the member i
has a default member initializer:
X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,
edited Nov 16 '18 at 5:57
answered Nov 15 '18 at 0:29
Shafik YaghmourShafik Yaghmour
126k23327543
126k23327543
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310690%2fimplicitly-defined-constructor-deleted-due-to-variant-member-n3690-n4140-vs-n46%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Notes are indeed non-normative. That's a general principle for ISO standards; works the same in ISO C.
– MSalters
Nov 15 '18 at 0:45
Related Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit default constructor?
– Shafik Yaghmour
Nov 15 '18 at 2:43