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*
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
add a comment |
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
@FrançoisAndrieux: so doesconst 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 parseunsigned charas 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
add a comment |
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
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
c++ c++14 c++17
asked 15 hours ago
Violet GiraffeViolet Giraffe
14.7k28135249
14.7k28135249
@FrançoisAndrieux: so doesconst 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 parseunsigned charas 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
add a comment |
@FrançoisAndrieux: so doesconst 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 parseunsigned charas 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
add a comment |
1 Answer
1
active
oldest
votes
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
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 Becauseuc{'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 aboutstatic_castinstead (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_thas spaces and is a valid simple-type-specifier.
– Arne Vogel
13 hours ago
|
show 2 more comments
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%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
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
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 Becauseuc{'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 aboutstatic_castinstead (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_thas spaces and is a valid simple-type-specifier.
– Arne Vogel
13 hours ago
|
show 2 more comments
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
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 Becauseuc{'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 aboutstatic_castinstead (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_thas spaces and is a valid simple-type-specifier.
– Arne Vogel
13 hours ago
|
show 2 more comments
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
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
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 Becauseuc{'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 aboutstatic_castinstead (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_thas spaces and is a valid simple-type-specifier.
– Arne Vogel
13 hours ago
|
show 2 more comments
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 Becauseuc{'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 aboutstatic_castinstead (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_thas 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
|
show 2 more comments
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%2f54947170%2fwhy-doesnt-auto-ch-unsigned-charp-compile-under-c-17%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
@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 charas 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