braced-init-list and unsigned types
gcc 8 and clang 7 do not accept the following code, which should default-construct a temporary of type unsigned int:
unsigned int ui = unsigned int{};
clang 7 reports an error such as
<source>:6:22: error: expected primary-expression before 'unsigned'
Visual C++ 2015 and 2017 accept this.
Obviously, this works with a type such as int, or any default-constructible class type.
Is this correct C++14 code (and in that case a bug of clang and gcc)? If not, why not? Which types other than unsigned types would suffer from the same restriction?
c++ initialization c++14 language-lawyer
add a comment |
gcc 8 and clang 7 do not accept the following code, which should default-construct a temporary of type unsigned int:
unsigned int ui = unsigned int{};
clang 7 reports an error such as
<source>:6:22: error: expected primary-expression before 'unsigned'
Visual C++ 2015 and 2017 accept this.
Obviously, this works with a type such as int, or any default-constructible class type.
Is this correct C++14 code (and in that case a bug of clang and gcc)? If not, why not? Which types other than unsigned types would suffer from the same restriction?
c++ initialization c++14 language-lawyer
3
Try(unsigned int){};. Think of the {} applied only tointand then there'sunsignedhanging where it shouldn't, hence the error message.
– DeiDei
Nov 16 '18 at 10:54
@DeiDei that is a syntax error in Standard C++ (parenthesized typename followed by{does not match any grammar rule)
– M.M
Dec 5 '18 at 2:17
add a comment |
gcc 8 and clang 7 do not accept the following code, which should default-construct a temporary of type unsigned int:
unsigned int ui = unsigned int{};
clang 7 reports an error such as
<source>:6:22: error: expected primary-expression before 'unsigned'
Visual C++ 2015 and 2017 accept this.
Obviously, this works with a type such as int, or any default-constructible class type.
Is this correct C++14 code (and in that case a bug of clang and gcc)? If not, why not? Which types other than unsigned types would suffer from the same restriction?
c++ initialization c++14 language-lawyer
gcc 8 and clang 7 do not accept the following code, which should default-construct a temporary of type unsigned int:
unsigned int ui = unsigned int{};
clang 7 reports an error such as
<source>:6:22: error: expected primary-expression before 'unsigned'
Visual C++ 2015 and 2017 accept this.
Obviously, this works with a type such as int, or any default-constructible class type.
Is this correct C++14 code (and in that case a bug of clang and gcc)? If not, why not? Which types other than unsigned types would suffer from the same restriction?
c++ initialization c++14 language-lawyer
c++ initialization c++14 language-lawyer
edited Dec 5 '18 at 1:35
songyuanyao
93.9k11182249
93.9k11182249
asked Nov 16 '18 at 10:49
user2019765user2019765
1367
1367
3
Try(unsigned int){};. Think of the {} applied only tointand then there'sunsignedhanging where it shouldn't, hence the error message.
– DeiDei
Nov 16 '18 at 10:54
@DeiDei that is a syntax error in Standard C++ (parenthesized typename followed by{does not match any grammar rule)
– M.M
Dec 5 '18 at 2:17
add a comment |
3
Try(unsigned int){};. Think of the {} applied only tointand then there'sunsignedhanging where it shouldn't, hence the error message.
– DeiDei
Nov 16 '18 at 10:54
@DeiDei that is a syntax error in Standard C++ (parenthesized typename followed by{does not match any grammar rule)
– M.M
Dec 5 '18 at 2:17
3
3
Try
(unsigned int){};. Think of the {} applied only to int and then there's unsigned hanging where it shouldn't, hence the error message.– DeiDei
Nov 16 '18 at 10:54
Try
(unsigned int){};. Think of the {} applied only to int and then there's unsigned hanging where it shouldn't, hence the error message.– DeiDei
Nov 16 '18 at 10:54
@DeiDei that is a syntax error in Standard C++ (parenthesized typename followed by
{ does not match any grammar rule)– M.M
Dec 5 '18 at 2:17
@DeiDei that is a syntax error in Standard C++ (parenthesized typename followed by
{ does not match any grammar rule)– M.M
Dec 5 '18 at 2:17
add a comment |
2 Answers
2
active
oldest
votes
new_type { expression-list(optional) } like unsigned int{} fits the syntax of explicit type conversion, which allows only single-word type name.
A single-word type name followed by a braced-init-list is a prvalue of the specified type
designating a temporary (until C++17)whose result object is (since C++17)direct-list-initialized with the specified braced-init-list.
Note that unsigned int is not a single-word type name, while int is. So int {} works fine.
This is same for functional cast expression,
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)orint*(expression)are not valid),
As a workaround, you can apply type alias, e.g.
using type = unsigned int;
type ui = type{};
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
1
@user2019765 I'm not sure, but I think both acceptingunsigned int{}and rejecting(unsigned int){}deosn't conform to the standard.
– songyuanyao
Nov 16 '18 at 11:14
(unsigned int){}is not a C-style cast: a C-style cast has form(type)expression, and{}is not an expression. With-pedantic, g++ warnsISO C++ forbids compound-literalsand clang warnscompound literals are a C99-specific feature.
– cpplearner
Nov 16 '18 at 13:57
|
show 8 more comments
"Int" is optional in "unsigned int".
Try simply:
unsigned ui = unsigned{};
It works.
Edit:
I found this answer:
Standard behavior for direct initialization of unsigned short
It's just because only single-word type name could be used in
functional cast expression, while unsigned short is not a single-word
type name; short is.
2
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
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%2f53336344%2fbraced-init-list-and-unsigned-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
new_type { expression-list(optional) } like unsigned int{} fits the syntax of explicit type conversion, which allows only single-word type name.
A single-word type name followed by a braced-init-list is a prvalue of the specified type
designating a temporary (until C++17)whose result object is (since C++17)direct-list-initialized with the specified braced-init-list.
Note that unsigned int is not a single-word type name, while int is. So int {} works fine.
This is same for functional cast expression,
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)orint*(expression)are not valid),
As a workaround, you can apply type alias, e.g.
using type = unsigned int;
type ui = type{};
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
1
@user2019765 I'm not sure, but I think both acceptingunsigned int{}and rejecting(unsigned int){}deosn't conform to the standard.
– songyuanyao
Nov 16 '18 at 11:14
(unsigned int){}is not a C-style cast: a C-style cast has form(type)expression, and{}is not an expression. With-pedantic, g++ warnsISO C++ forbids compound-literalsand clang warnscompound literals are a C99-specific feature.
– cpplearner
Nov 16 '18 at 13:57
|
show 8 more comments
new_type { expression-list(optional) } like unsigned int{} fits the syntax of explicit type conversion, which allows only single-word type name.
A single-word type name followed by a braced-init-list is a prvalue of the specified type
designating a temporary (until C++17)whose result object is (since C++17)direct-list-initialized with the specified braced-init-list.
Note that unsigned int is not a single-word type name, while int is. So int {} works fine.
This is same for functional cast expression,
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)orint*(expression)are not valid),
As a workaround, you can apply type alias, e.g.
using type = unsigned int;
type ui = type{};
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
1
@user2019765 I'm not sure, but I think both acceptingunsigned int{}and rejecting(unsigned int){}deosn't conform to the standard.
– songyuanyao
Nov 16 '18 at 11:14
(unsigned int){}is not a C-style cast: a C-style cast has form(type)expression, and{}is not an expression. With-pedantic, g++ warnsISO C++ forbids compound-literalsand clang warnscompound literals are a C99-specific feature.
– cpplearner
Nov 16 '18 at 13:57
|
show 8 more comments
new_type { expression-list(optional) } like unsigned int{} fits the syntax of explicit type conversion, which allows only single-word type name.
A single-word type name followed by a braced-init-list is a prvalue of the specified type
designating a temporary (until C++17)whose result object is (since C++17)direct-list-initialized with the specified braced-init-list.
Note that unsigned int is not a single-word type name, while int is. So int {} works fine.
This is same for functional cast expression,
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)orint*(expression)are not valid),
As a workaround, you can apply type alias, e.g.
using type = unsigned int;
type ui = type{};
new_type { expression-list(optional) } like unsigned int{} fits the syntax of explicit type conversion, which allows only single-word type name.
A single-word type name followed by a braced-init-list is a prvalue of the specified type
designating a temporary (until C++17)whose result object is (since C++17)direct-list-initialized with the specified braced-init-list.
Note that unsigned int is not a single-word type name, while int is. So int {} works fine.
This is same for functional cast expression,
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)orint*(expression)are not valid),
As a workaround, you can apply type alias, e.g.
using type = unsigned int;
type ui = type{};
edited Nov 16 '18 at 15:46
answered Nov 16 '18 at 10:55
songyuanyaosongyuanyao
93.9k11182249
93.9k11182249
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
1
@user2019765 I'm not sure, but I think both acceptingunsigned int{}and rejecting(unsigned int){}deosn't conform to the standard.
– songyuanyao
Nov 16 '18 at 11:14
(unsigned int){}is not a C-style cast: a C-style cast has form(type)expression, and{}is not an expression. With-pedantic, g++ warnsISO C++ forbids compound-literalsand clang warnscompound literals are a C99-specific feature.
– cpplearner
Nov 16 '18 at 13:57
|
show 8 more comments
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
1
@user2019765 I'm not sure, but I think both acceptingunsigned int{}and rejecting(unsigned int){}deosn't conform to the standard.
– songyuanyao
Nov 16 '18 at 11:14
(unsigned int){}is not a C-style cast: a C-style cast has form(type)expression, and{}is not an expression. With-pedantic, g++ warnsISO C++ forbids compound-literalsand clang warnscompound literals are a C99-specific feature.
– cpplearner
Nov 16 '18 at 13:57
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
Thanks. Obviously, it is not a single word, I wasn't aware of this constraint.
– user2019765
Nov 16 '18 at 11:09
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
@user2019765 I agree this is not easy to notice; even it's obvious if you realize it.
– songyuanyao
Nov 16 '18 at 11:11
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
Interestingly, adding parentheses works with clang, but not with Visual C++, there it yields an error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
– user2019765
Nov 16 '18 at 11:12
1
1
@user2019765 I'm not sure, but I think both accepting
unsigned int{} and rejecting (unsigned int){} deosn't conform to the standard.– songyuanyao
Nov 16 '18 at 11:14
@user2019765 I'm not sure, but I think both accepting
unsigned int{} and rejecting (unsigned int){} deosn't conform to the standard.– songyuanyao
Nov 16 '18 at 11:14
(unsigned int){} is not a C-style cast: a C-style cast has form (type)expression, and {} is not an expression. With -pedantic, g++ warns ISO C++ forbids compound-literals and clang warns compound literals are a C99-specific feature.– cpplearner
Nov 16 '18 at 13:57
(unsigned int){} is not a C-style cast: a C-style cast has form (type)expression, and {} is not an expression. With -pedantic, g++ warns ISO C++ forbids compound-literals and clang warns compound literals are a C99-specific feature.– cpplearner
Nov 16 '18 at 13:57
|
show 8 more comments
"Int" is optional in "unsigned int".
Try simply:
unsigned ui = unsigned{};
It works.
Edit:
I found this answer:
Standard behavior for direct initialization of unsigned short
It's just because only single-word type name could be used in
functional cast expression, while unsigned short is not a single-word
type name; short is.
2
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
add a comment |
"Int" is optional in "unsigned int".
Try simply:
unsigned ui = unsigned{};
It works.
Edit:
I found this answer:
Standard behavior for direct initialization of unsigned short
It's just because only single-word type name could be used in
functional cast expression, while unsigned short is not a single-word
type name; short is.
2
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
add a comment |
"Int" is optional in "unsigned int".
Try simply:
unsigned ui = unsigned{};
It works.
Edit:
I found this answer:
Standard behavior for direct initialization of unsigned short
It's just because only single-word type name could be used in
functional cast expression, while unsigned short is not a single-word
type name; short is.
"Int" is optional in "unsigned int".
Try simply:
unsigned ui = unsigned{};
It works.
Edit:
I found this answer:
Standard behavior for direct initialization of unsigned short
It's just because only single-word type name could be used in
functional cast expression, while unsigned short is not a single-word
type name; short is.
edited Nov 16 '18 at 11:05
answered Nov 16 '18 at 10:55
artonaartona
71248
71248
2
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
add a comment |
2
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
2
2
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
Thanks for your suggestion, but my question was not how to fix the expression, but if it is correct.
– user2019765
Nov 16 '18 at 11:03
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%2f53336344%2fbraced-init-list-and-unsigned-types%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
3
Try
(unsigned int){};. Think of the {} applied only tointand then there'sunsignedhanging where it shouldn't, hence the error message.– DeiDei
Nov 16 '18 at 10:54
@DeiDei that is a syntax error in Standard C++ (parenthesized typename followed by
{does not match any grammar rule)– M.M
Dec 5 '18 at 2:17