C++20 bit_cast vs reinterpret_cast
According to the last meeting of the ISO C++ Commitee, bit-cast will be introduced in C++20 standard.
I know that reinterpret_cast is not suitable for this job due to type allasing rules but my question is why did they choose not to extend the reinterpret_cast to treat the object like it bit sequence representation and prefered to give this functionallity as a new language construct?
c++ language-lawyer type-alias c++20
add a comment |
According to the last meeting of the ISO C++ Commitee, bit-cast will be introduced in C++20 standard.
I know that reinterpret_cast is not suitable for this job due to type allasing rules but my question is why did they choose not to extend the reinterpret_cast to treat the object like it bit sequence representation and prefered to give this functionallity as a new language construct?
c++ language-lawyer type-alias c++20
In what way are you suggesting thatreinterpret_castbe extended? That is, what would code that uses this hypothetically look like?
– Nicol Bolas
Nov 20 at 21:23
@NicolBolas: How about allowingreinterpret_castto do this:float x = 1.0f; reinterpret_cast<unsigned int>(x);.
– geza
Nov 20 at 21:29
I was thinking exactly like @geza suggested
– bogdan tudose
Nov 20 at 21:34
add a comment |
According to the last meeting of the ISO C++ Commitee, bit-cast will be introduced in C++20 standard.
I know that reinterpret_cast is not suitable for this job due to type allasing rules but my question is why did they choose not to extend the reinterpret_cast to treat the object like it bit sequence representation and prefered to give this functionallity as a new language construct?
c++ language-lawyer type-alias c++20
According to the last meeting of the ISO C++ Commitee, bit-cast will be introduced in C++20 standard.
I know that reinterpret_cast is not suitable for this job due to type allasing rules but my question is why did they choose not to extend the reinterpret_cast to treat the object like it bit sequence representation and prefered to give this functionallity as a new language construct?
c++ language-lawyer type-alias c++20
c++ language-lawyer type-alias c++20
edited Nov 21 at 10:43
asked Nov 20 at 21:16
bogdan tudose
867
867
In what way are you suggesting thatreinterpret_castbe extended? That is, what would code that uses this hypothetically look like?
– Nicol Bolas
Nov 20 at 21:23
@NicolBolas: How about allowingreinterpret_castto do this:float x = 1.0f; reinterpret_cast<unsigned int>(x);.
– geza
Nov 20 at 21:29
I was thinking exactly like @geza suggested
– bogdan tudose
Nov 20 at 21:34
add a comment |
In what way are you suggesting thatreinterpret_castbe extended? That is, what would code that uses this hypothetically look like?
– Nicol Bolas
Nov 20 at 21:23
@NicolBolas: How about allowingreinterpret_castto do this:float x = 1.0f; reinterpret_cast<unsigned int>(x);.
– geza
Nov 20 at 21:29
I was thinking exactly like @geza suggested
– bogdan tudose
Nov 20 at 21:34
In what way are you suggesting that
reinterpret_cast be extended? That is, what would code that uses this hypothetically look like?– Nicol Bolas
Nov 20 at 21:23
In what way are you suggesting that
reinterpret_cast be extended? That is, what would code that uses this hypothetically look like?– Nicol Bolas
Nov 20 at 21:23
@NicolBolas: How about allowing
reinterpret_cast to do this: float x = 1.0f; reinterpret_cast<unsigned int>(x);.– geza
Nov 20 at 21:29
@NicolBolas: How about allowing
reinterpret_cast to do this: float x = 1.0f; reinterpret_cast<unsigned int>(x);.– geza
Nov 20 at 21:29
I was thinking exactly like @geza suggested
– bogdan tudose
Nov 20 at 21:34
I was thinking exactly like @geza suggested
– bogdan tudose
Nov 20 at 21:34
add a comment |
1 Answer
1
active
oldest
votes
Well, there is one obvious reason: because it wouldn't do everything that bit_cast does. Even in the C++20 world where we can allocate memory at compile time, reinterpret_cast is forbidden in constexpr functions. One of the explicit goals of bit_cast is to be able to do these sorts of things at compile-time:
Furthermore, it is currently impossible to implement a
constexprbit-cast function, asmemcpyitself isn’tconstexpr. Marking the proposed function asconstexprdoesn’t require or preventmemcpyfrom becomingconstexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has abitcastopcode).
Now, you could say that you could just extend this specific usage of reinterpret_cast to constexpr contexts. But that makes the rules complicated. Instead of simply knowing that reinterpret_cast can't be used in constexpr code period, you have to remember the specific forms of reinterpret_cast that can't be used.
Also, there are practical concerns. Even if you wanted to go the reinterpret_cast route, std::bit_cast is a library function. And it's always easier to get a library feature through the committee than a language feature, even if it would receive some compiler support.
Then there's the more subjective stuff. reinterpret_cast is generally considered an inherently dangerous operation, indicative of "cheating" the type system in some way. By contrast, bit_cast is not. It is generating a new object as if by copying its value representation from an existing one. It's a low-level tool, but it's not a tool that messes with the type system. So it would be strange to spell a "safe" operation the same way you spell a "dangerous" one.
Indeed, if you did spell them the same way, it starts raising questions as to why this is reasonably well-defined:
float f = 20.4f;
int i = reinterpret_cast<int>(f);
But this is somehow bad:
float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
And sure, a language lawyer or someone familiar with the strict aliasing rule would understand why the latter is bad. But for the lay person, if it is fine to use reinterpret_cast to do a bit-conversion, it is unclear why it is wrong to use reinterpret_cast to convert pointers/references and interpret an existing object as a converted type.
Different tools should be spelled differently.
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%2f53401654%2fc20-bit-cast-vs-reinterpret-cast%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
Well, there is one obvious reason: because it wouldn't do everything that bit_cast does. Even in the C++20 world where we can allocate memory at compile time, reinterpret_cast is forbidden in constexpr functions. One of the explicit goals of bit_cast is to be able to do these sorts of things at compile-time:
Furthermore, it is currently impossible to implement a
constexprbit-cast function, asmemcpyitself isn’tconstexpr. Marking the proposed function asconstexprdoesn’t require or preventmemcpyfrom becomingconstexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has abitcastopcode).
Now, you could say that you could just extend this specific usage of reinterpret_cast to constexpr contexts. But that makes the rules complicated. Instead of simply knowing that reinterpret_cast can't be used in constexpr code period, you have to remember the specific forms of reinterpret_cast that can't be used.
Also, there are practical concerns. Even if you wanted to go the reinterpret_cast route, std::bit_cast is a library function. And it's always easier to get a library feature through the committee than a language feature, even if it would receive some compiler support.
Then there's the more subjective stuff. reinterpret_cast is generally considered an inherently dangerous operation, indicative of "cheating" the type system in some way. By contrast, bit_cast is not. It is generating a new object as if by copying its value representation from an existing one. It's a low-level tool, but it's not a tool that messes with the type system. So it would be strange to spell a "safe" operation the same way you spell a "dangerous" one.
Indeed, if you did spell them the same way, it starts raising questions as to why this is reasonably well-defined:
float f = 20.4f;
int i = reinterpret_cast<int>(f);
But this is somehow bad:
float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
And sure, a language lawyer or someone familiar with the strict aliasing rule would understand why the latter is bad. But for the lay person, if it is fine to use reinterpret_cast to do a bit-conversion, it is unclear why it is wrong to use reinterpret_cast to convert pointers/references and interpret an existing object as a converted type.
Different tools should be spelled differently.
add a comment |
Well, there is one obvious reason: because it wouldn't do everything that bit_cast does. Even in the C++20 world where we can allocate memory at compile time, reinterpret_cast is forbidden in constexpr functions. One of the explicit goals of bit_cast is to be able to do these sorts of things at compile-time:
Furthermore, it is currently impossible to implement a
constexprbit-cast function, asmemcpyitself isn’tconstexpr. Marking the proposed function asconstexprdoesn’t require or preventmemcpyfrom becomingconstexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has abitcastopcode).
Now, you could say that you could just extend this specific usage of reinterpret_cast to constexpr contexts. But that makes the rules complicated. Instead of simply knowing that reinterpret_cast can't be used in constexpr code period, you have to remember the specific forms of reinterpret_cast that can't be used.
Also, there are practical concerns. Even if you wanted to go the reinterpret_cast route, std::bit_cast is a library function. And it's always easier to get a library feature through the committee than a language feature, even if it would receive some compiler support.
Then there's the more subjective stuff. reinterpret_cast is generally considered an inherently dangerous operation, indicative of "cheating" the type system in some way. By contrast, bit_cast is not. It is generating a new object as if by copying its value representation from an existing one. It's a low-level tool, but it's not a tool that messes with the type system. So it would be strange to spell a "safe" operation the same way you spell a "dangerous" one.
Indeed, if you did spell them the same way, it starts raising questions as to why this is reasonably well-defined:
float f = 20.4f;
int i = reinterpret_cast<int>(f);
But this is somehow bad:
float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
And sure, a language lawyer or someone familiar with the strict aliasing rule would understand why the latter is bad. But for the lay person, if it is fine to use reinterpret_cast to do a bit-conversion, it is unclear why it is wrong to use reinterpret_cast to convert pointers/references and interpret an existing object as a converted type.
Different tools should be spelled differently.
add a comment |
Well, there is one obvious reason: because it wouldn't do everything that bit_cast does. Even in the C++20 world where we can allocate memory at compile time, reinterpret_cast is forbidden in constexpr functions. One of the explicit goals of bit_cast is to be able to do these sorts of things at compile-time:
Furthermore, it is currently impossible to implement a
constexprbit-cast function, asmemcpyitself isn’tconstexpr. Marking the proposed function asconstexprdoesn’t require or preventmemcpyfrom becomingconstexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has abitcastopcode).
Now, you could say that you could just extend this specific usage of reinterpret_cast to constexpr contexts. But that makes the rules complicated. Instead of simply knowing that reinterpret_cast can't be used in constexpr code period, you have to remember the specific forms of reinterpret_cast that can't be used.
Also, there are practical concerns. Even if you wanted to go the reinterpret_cast route, std::bit_cast is a library function. And it's always easier to get a library feature through the committee than a language feature, even if it would receive some compiler support.
Then there's the more subjective stuff. reinterpret_cast is generally considered an inherently dangerous operation, indicative of "cheating" the type system in some way. By contrast, bit_cast is not. It is generating a new object as if by copying its value representation from an existing one. It's a low-level tool, but it's not a tool that messes with the type system. So it would be strange to spell a "safe" operation the same way you spell a "dangerous" one.
Indeed, if you did spell them the same way, it starts raising questions as to why this is reasonably well-defined:
float f = 20.4f;
int i = reinterpret_cast<int>(f);
But this is somehow bad:
float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
And sure, a language lawyer or someone familiar with the strict aliasing rule would understand why the latter is bad. But for the lay person, if it is fine to use reinterpret_cast to do a bit-conversion, it is unclear why it is wrong to use reinterpret_cast to convert pointers/references and interpret an existing object as a converted type.
Different tools should be spelled differently.
Well, there is one obvious reason: because it wouldn't do everything that bit_cast does. Even in the C++20 world where we can allocate memory at compile time, reinterpret_cast is forbidden in constexpr functions. One of the explicit goals of bit_cast is to be able to do these sorts of things at compile-time:
Furthermore, it is currently impossible to implement a
constexprbit-cast function, asmemcpyitself isn’tconstexpr. Marking the proposed function asconstexprdoesn’t require or preventmemcpyfrom becomingconstexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has abitcastopcode).
Now, you could say that you could just extend this specific usage of reinterpret_cast to constexpr contexts. But that makes the rules complicated. Instead of simply knowing that reinterpret_cast can't be used in constexpr code period, you have to remember the specific forms of reinterpret_cast that can't be used.
Also, there are practical concerns. Even if you wanted to go the reinterpret_cast route, std::bit_cast is a library function. And it's always easier to get a library feature through the committee than a language feature, even if it would receive some compiler support.
Then there's the more subjective stuff. reinterpret_cast is generally considered an inherently dangerous operation, indicative of "cheating" the type system in some way. By contrast, bit_cast is not. It is generating a new object as if by copying its value representation from an existing one. It's a low-level tool, but it's not a tool that messes with the type system. So it would be strange to spell a "safe" operation the same way you spell a "dangerous" one.
Indeed, if you did spell them the same way, it starts raising questions as to why this is reasonably well-defined:
float f = 20.4f;
int i = reinterpret_cast<int>(f);
But this is somehow bad:
float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
And sure, a language lawyer or someone familiar with the strict aliasing rule would understand why the latter is bad. But for the lay person, if it is fine to use reinterpret_cast to do a bit-conversion, it is unclear why it is wrong to use reinterpret_cast to convert pointers/references and interpret an existing object as a converted type.
Different tools should be spelled differently.
edited Nov 21 at 14:34
answered Nov 20 at 21:57
Nicol Bolas
281k33464640
281k33464640
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53401654%2fc20-bit-cast-vs-reinterpret-cast%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
In what way are you suggesting that
reinterpret_castbe extended? That is, what would code that uses this hypothetically look like?– Nicol Bolas
Nov 20 at 21:23
@NicolBolas: How about allowing
reinterpret_castto do this:float x = 1.0f; reinterpret_cast<unsigned int>(x);.– geza
Nov 20 at 21:29
I was thinking exactly like @geza suggested
– bogdan tudose
Nov 20 at 21:34