braced-init-list and unsigned types












7















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?










share|improve this question




















  • 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













  • @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


















7















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?










share|improve this question




















  • 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













  • @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
















7












7








7








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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
















  • 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













  • @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














2 Answers
2






active

oldest

votes


















8














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) or int*(expression) are not valid),




As a workaround, you can apply type alias, e.g.



using type = unsigned int;
type ui = type{};





share|improve this answer


























  • 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 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



















3














"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.







share|improve this answer





















  • 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












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
});


}
});














draft saved

draft discarded


















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









8














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) or int*(expression) are not valid),




As a workaround, you can apply type alias, e.g.



using type = unsigned int;
type ui = type{};





share|improve this answer


























  • 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 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
















8














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) or int*(expression) are not valid),




As a workaround, you can apply type alias, e.g.



using type = unsigned int;
type ui = type{};





share|improve this answer


























  • 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 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














8












8








8







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) or int*(expression) are not valid),




As a workaround, you can apply type alias, e.g.



using type = unsigned int;
type ui = type{};





share|improve this answer















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) or int*(expression) are not valid),




As a workaround, you can apply type alias, e.g.



using type = unsigned int;
type ui = type{};






share|improve this answer














share|improve this answer



share|improve this answer








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 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



















  • 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 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

















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













3














"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.







share|improve this answer





















  • 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
















3














"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.







share|improve this answer





















  • 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














3












3








3







"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.







share|improve this answer















"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.








share|improve this answer














share|improve this answer



share|improve this answer








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














  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

List item for chat from Array inside array React Native

Thiostrepton

Caerphilly