Why doesn't “auto ch = unsigned char{'p'}” compile under C++ 17?What is an unsigned char?Why does C++...

How can animals be objects of ethics without being subjects as well?

Every character has a name - does this lead to too many named characters?

How do you funnel food off a cutting board?

Broken patches on a road

Word or phrase for showing great skill at something without formal training in it

How to deal with an incendiary email that was recalled

What to do when being responsible for data protection in your lab, yet advice is ignored?

Why does String.replaceAll() work differently in Java 8 from Java 9?

Explain the objections to these measures against human trafficking

Placing an adverb between a verb and an object?

Why are the books in the Game of Thrones citadel library shelved spine inwards?

Can a person refuse a presidential pardon?

How to avoid being sexist when trying to employ someone to function in a very sexist environment?

Why do neural networks need so many training examples to perform?

Why is "points exist" not an axiom in geometry?

How to tag distinct options/entities without giving any an implicit priority or suggested order?

What is the wife of a henpecked husband called?

Citing paywalled articles accessed via illegal web sharing

Can you earn endless XP using a Flameskull and its self-revival feature?

Am I a Rude Number?

Would these multi-classing house rules cause unintended problems?

Why avoid shared user accounts?

Process to change collation on a database

Pre-1980's science fiction short story: alien disguised as a woman shot by a gangster, has tentacles coming out of her breasts when remaking her body



Why doesn't “auto ch = unsigned char{'p'}” compile under C++ 17?


What is an unsigned char?Why does C++ compilation take so long?Why do we need virtual functions in C++?Why is this program erroneously rejected by three C++ compilers?Why should C++ programmers minimize use of 'new'?Why is reading lines from stdin much slower in C++ than Python?g++ gives error : invalid initialization of reference of type ‘char&’ from expression of type ‘unsigned char’basic_string of unsigned char Value TypeError when attempting to static_cast<> const char[] to unsigned char *How do I cast a const char* to a const unsigned char*













22















I'm puzzled. Isn't const auto ch = unsigned char{'p'}; a perfectly valid initialization expression? Fails to be compiled by all three major compilers with almost identical error messages:




error: expected '(' for function-style cast or type construction




Swapping curly braces for ('p') changes nothing.
It does, however, compile without the signed or unsigned keyword.



Online demo.










share|improve this question























  • @FrançoisAndrieux: so does const auto ch = static_cast<unsigned char>('p'), but that's conversion, not initialization.

    – Violet Giraffe
    15 hours ago








  • 3





    using T = unsigned char; const auto ch = T{'p'}; seems to work.

    – François Andrieux
    15 hours ago











  • @FrançoisAndrieux: Hm, do you think the compiler simply fails to parse unsigned char as a single type name in this context?

    – Violet Giraffe
    15 hours ago






  • 1





    const auto ch = (unsigned char){'p'};?

    – Yakk - Adam Nevraumont
    11 hours ago
















22















I'm puzzled. Isn't const auto ch = unsigned char{'p'}; a perfectly valid initialization expression? Fails to be compiled by all three major compilers with almost identical error messages:




error: expected '(' for function-style cast or type construction




Swapping curly braces for ('p') changes nothing.
It does, however, compile without the signed or unsigned keyword.



Online demo.










share|improve this question























  • @FrançoisAndrieux: so does const auto ch = static_cast<unsigned char>('p'), but that's conversion, not initialization.

    – Violet Giraffe
    15 hours ago








  • 3





    using T = unsigned char; const auto ch = T{'p'}; seems to work.

    – François Andrieux
    15 hours ago











  • @FrançoisAndrieux: Hm, do you think the compiler simply fails to parse unsigned char as a single type name in this context?

    – Violet Giraffe
    15 hours ago






  • 1





    const auto ch = (unsigned char){'p'};?

    – Yakk - Adam Nevraumont
    11 hours ago














22












22








22


2






I'm puzzled. Isn't const auto ch = unsigned char{'p'}; a perfectly valid initialization expression? Fails to be compiled by all three major compilers with almost identical error messages:




error: expected '(' for function-style cast or type construction




Swapping curly braces for ('p') changes nothing.
It does, however, compile without the signed or unsigned keyword.



Online demo.










share|improve this question














I'm puzzled. Isn't const auto ch = unsigned char{'p'}; a perfectly valid initialization expression? Fails to be compiled by all three major compilers with almost identical error messages:




error: expected '(' for function-style cast or type construction




Swapping curly braces for ('p') changes nothing.
It does, however, compile without the signed or unsigned keyword.



Online demo.







c++ c++14 c++17






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 15 hours ago









Violet GiraffeViolet Giraffe

14.7k28135249




14.7k28135249













  • @FrançoisAndrieux: so does const auto ch = static_cast<unsigned char>('p'), but that's conversion, not initialization.

    – Violet Giraffe
    15 hours ago








  • 3





    using T = unsigned char; const auto ch = T{'p'}; seems to work.

    – François Andrieux
    15 hours ago











  • @FrançoisAndrieux: Hm, do you think the compiler simply fails to parse unsigned char as a single type name in this context?

    – Violet Giraffe
    15 hours ago






  • 1





    const auto ch = (unsigned char){'p'};?

    – Yakk - Adam Nevraumont
    11 hours ago



















  • @FrançoisAndrieux: so does const auto ch = static_cast<unsigned char>('p'), but that's conversion, not initialization.

    – Violet Giraffe
    15 hours ago








  • 3





    using T = unsigned char; const auto ch = T{'p'}; seems to work.

    – François Andrieux
    15 hours ago











  • @FrançoisAndrieux: Hm, do you think the compiler simply fails to parse unsigned char as a single type name in this context?

    – Violet Giraffe
    15 hours ago






  • 1





    const auto ch = (unsigned char){'p'};?

    – Yakk - Adam Nevraumont
    11 hours ago

















@FrançoisAndrieux: so does const auto ch = static_cast<unsigned char>('p'), but that's conversion, not initialization.

– Violet Giraffe
15 hours ago







@FrançoisAndrieux: so does const auto ch = static_cast<unsigned char>('p'), but that's conversion, not initialization.

– Violet Giraffe
15 hours ago






3




3





using T = unsigned char; const auto ch = T{'p'}; seems to work.

– François Andrieux
15 hours ago





using T = unsigned char; const auto ch = T{'p'}; seems to work.

– François Andrieux
15 hours ago













@FrançoisAndrieux: Hm, do you think the compiler simply fails to parse unsigned char as a single type name in this context?

– Violet Giraffe
15 hours ago





@FrançoisAndrieux: Hm, do you think the compiler simply fails to parse unsigned char as a single type name in this context?

– Violet Giraffe
15 hours ago




1




1





const auto ch = (unsigned char){'p'};?

– Yakk - Adam Nevraumont
11 hours ago





const auto ch = (unsigned char){'p'};?

– Yakk - Adam Nevraumont
11 hours ago












1 Answer
1






active

oldest

votes


















31














Because only single-word type name could be used for this kind of explicit type conversion.




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.




unsigned char is not a single-word type name, while char is. And this is true for functional cast expression too, that's why ('p') doesn't work either.



As the workaround, you can



using uc = unsigned char;  // or use typedef
const auto ch = uc{'p'};


Or change it to other cast styles.



const auto ch = (unsigned char) 'p';  // c-style cast expression
const auto ch = static_cast<unsigned char>('p'); // static_cast conversion





share|improve this answer





















  • 5





    Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

    – Violet Giraffe
    14 hours ago






  • 1





    @VioletGiraffe To be honest I don't know; I only know that the standard says so.

    – songyuanyao
    14 hours ago






  • 1





    @VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

    – NathanOliver
    13 hours ago






  • 1





    @curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

    – NathanOliver
    13 hours ago






  • 4





    C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

    – Arne Vogel
    13 hours ago











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%2f54947170%2fwhy-doesnt-auto-ch-unsigned-charp-compile-under-c-17%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









31














Because only single-word type name could be used for this kind of explicit type conversion.




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.




unsigned char is not a single-word type name, while char is. And this is true for functional cast expression too, that's why ('p') doesn't work either.



As the workaround, you can



using uc = unsigned char;  // or use typedef
const auto ch = uc{'p'};


Or change it to other cast styles.



const auto ch = (unsigned char) 'p';  // c-style cast expression
const auto ch = static_cast<unsigned char>('p'); // static_cast conversion





share|improve this answer





















  • 5





    Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

    – Violet Giraffe
    14 hours ago






  • 1





    @VioletGiraffe To be honest I don't know; I only know that the standard says so.

    – songyuanyao
    14 hours ago






  • 1





    @VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

    – NathanOliver
    13 hours ago






  • 1





    @curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

    – NathanOliver
    13 hours ago






  • 4





    C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

    – Arne Vogel
    13 hours ago
















31














Because only single-word type name could be used for this kind of explicit type conversion.




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.




unsigned char is not a single-word type name, while char is. And this is true for functional cast expression too, that's why ('p') doesn't work either.



As the workaround, you can



using uc = unsigned char;  // or use typedef
const auto ch = uc{'p'};


Or change it to other cast styles.



const auto ch = (unsigned char) 'p';  // c-style cast expression
const auto ch = static_cast<unsigned char>('p'); // static_cast conversion





share|improve this answer





















  • 5





    Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

    – Violet Giraffe
    14 hours ago






  • 1





    @VioletGiraffe To be honest I don't know; I only know that the standard says so.

    – songyuanyao
    14 hours ago






  • 1





    @VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

    – NathanOliver
    13 hours ago






  • 1





    @curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

    – NathanOliver
    13 hours ago






  • 4





    C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

    – Arne Vogel
    13 hours ago














31












31








31







Because only single-word type name could be used for this kind of explicit type conversion.




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.




unsigned char is not a single-word type name, while char is. And this is true for functional cast expression too, that's why ('p') doesn't work either.



As the workaround, you can



using uc = unsigned char;  // or use typedef
const auto ch = uc{'p'};


Or change it to other cast styles.



const auto ch = (unsigned char) 'p';  // c-style cast expression
const auto ch = static_cast<unsigned char>('p'); // static_cast conversion





share|improve this answer















Because only single-word type name could be used for this kind of explicit type conversion.




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.




unsigned char is not a single-word type name, while char is. And this is true for functional cast expression too, that's why ('p') doesn't work either.



As the workaround, you can



using uc = unsigned char;  // or use typedef
const auto ch = uc{'p'};


Or change it to other cast styles.



const auto ch = (unsigned char) 'p';  // c-style cast expression
const auto ch = static_cast<unsigned char>('p'); // static_cast conversion






share|improve this answer














share|improve this answer



share|improve this answer








edited 13 hours ago

























answered 14 hours ago









songyuanyaosongyuanyao

92.2k11177242




92.2k11177242








  • 5





    Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

    – Violet Giraffe
    14 hours ago






  • 1





    @VioletGiraffe To be honest I don't know; I only know that the standard says so.

    – songyuanyao
    14 hours ago






  • 1





    @VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

    – NathanOliver
    13 hours ago






  • 1





    @curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

    – NathanOliver
    13 hours ago






  • 4





    C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

    – Arne Vogel
    13 hours ago














  • 5





    Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

    – Violet Giraffe
    14 hours ago






  • 1





    @VioletGiraffe To be honest I don't know; I only know that the standard says so.

    – songyuanyao
    14 hours ago






  • 1





    @VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

    – NathanOliver
    13 hours ago






  • 1





    @curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

    – NathanOliver
    13 hours ago






  • 4





    C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

    – Arne Vogel
    13 hours ago








5




5





Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

– Violet Giraffe
14 hours ago





Do you happen to know the reason for this limitation? Like, if multi-word type names were allowed here, what other things would become broken?

– Violet Giraffe
14 hours ago




1




1





@VioletGiraffe To be honest I don't know; I only know that the standard says so.

– songyuanyao
14 hours ago





@VioletGiraffe To be honest I don't know; I only know that the standard says so.

– songyuanyao
14 hours ago




1




1





@VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

– NathanOliver
13 hours ago





@VioletGiraffe Because uc{'p'}/uc('p') is a functional cast. A function name can't have a space in it so neither can the type name.

– NathanOliver
13 hours ago




1




1





@curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

– NathanOliver
13 hours ago





@curiousguy For all intents and purposes it is. If the type is a class type then the constructor is called. the cast and call have the exact same syntax and grammar.

– NathanOliver
13 hours ago




4




4





C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

– Arne Vogel
13 hours ago





C-style cast, really? How about static_cast instead (or in case Boost is used, boost::implicit_cast)? The language allows a simple-type-specifier or (in a template) a typename-specifier, BTW, in a function-style cast, to be precise. Your statement that it "can't have a space" is slightly misleading because e.g. std :: uint8_t has spaces and is a valid simple-type-specifier.

– Arne Vogel
13 hours ago




















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%2f54947170%2fwhy-doesnt-auto-ch-unsigned-charp-compile-under-c-17%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

Webac Holding Inhaltsverzeichnis Geschichte | Organisationsstruktur | Tochterfirmen |...

What's the meaning of a knight fighting a snail in medieval book illustrations?What is the meaning of a glove...

Salamanca Inhaltsverzeichnis Lage und Klima | Bevölkerungsentwicklung | Geschichte | Kultur und...