Is it Legal to reinterpret_cast to a void* Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live! The [wrap] tag is in the process of being burninatedWhen to use reinterpret_cast?Should I use static_cast or reinterpret_cast when casting a void* to whateverWhen should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?reinterpret_castImage Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionReplacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsReading from void pointer — reinterpret_cast okay?Using a pointer for casting char* to unsigned char*C++ syntax for const void pointerC++ swap content of two void*How Does void Work With Type Aliassing?
How to answer "Have you ever been terminated?"
How do I stop a creek from eroding my steep embankment?
How do I make this wiring inside cabinet safer? (Pic)
Can anything be seen from the center of the Boötes void? How dark would it be?
Is the Standard Deduction better than Itemized when both are the same amount?
What would be the ideal power source for a cybernetic eye?
Closed form of recurrent arithmetic series summation
Is there any way for the UK Prime Minister to make a motion directly dependent on Government confidence?
First console to have temporary backward compatibility
Trademark violation for app?
How to show element name in portuguese using elements package?
Wu formula for manifolds with boundary
Fantasy story; one type of magic grows in power with use, but the more powerful they are, they more they are drawn to travel to their source
Most bit efficient text communication method?
Can an alien society believe that their star system is the universe?
What are the out-of-universe reasons for the references to Toby Maguire-era Spider-Man in ITSV
Do square wave exist?
Declining "dulcis" in context
An adverb for when you're not exaggerating
Is it ethical to give a final exam after the professor has quit before teaching the remaining chapters of the course?
What's the meaning of "fortified infraction restraint"?
Why wasn't DOSKEY integrated with COMMAND.COM?
2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?
Does classifying an integer as a discrete log require it be part of a multiplicative group?
Is it Legal to reinterpret_cast to a void*
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!
The [wrap] tag is in the process of being burninatedWhen to use reinterpret_cast?Should I use static_cast or reinterpret_cast when casting a void* to whateverWhen should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?reinterpret_castImage Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionReplacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsReading from void pointer — reinterpret_cast okay?Using a pointer for casting char* to unsigned char*C++ syntax for const void pointerC++ swap content of two void*How Does void Work With Type Aliassing?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I was looking at https://en.cppreference.com/w/cpp/language/reinterpret_cast and I noticed that it specifies the legal types we can always cast to:
byte*
char*
unsigned char*
But I did not see void*
in the list. Is this an oversight? My use case requires a reinterpret_cast
because I'm casting from an int**
to a void*
. And I will eventually cast from the void*
back to an int**
.
c++ pointers void-pointers reinterpret-cast double-pointer
add a comment |
I was looking at https://en.cppreference.com/w/cpp/language/reinterpret_cast and I noticed that it specifies the legal types we can always cast to:
byte*
char*
unsigned char*
But I did not see void*
in the list. Is this an oversight? My use case requires a reinterpret_cast
because I'm casting from an int**
to a void*
. And I will eventually cast from the void*
back to an int**
.
c++ pointers void-pointers reinterpret-cast double-pointer
2
"it specifies the legal types we can always cast to" This seems like your invention. That page does not say anything similar to that.
– cpplearner
10 hours ago
1
You don't need areinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl
– Max Langhof
10 hours ago
I've reopened the question because I didn't see only the top answer applies to this. Leaving a link here: stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
– NathanOliver
10 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
10 hours ago
@FrançoisAndrieux Ugh, I knew that. I'm just forgetting like an idiot. Could you just post that as an answer and I'll accept?
– Jonathan Mee
10 hours ago
add a comment |
I was looking at https://en.cppreference.com/w/cpp/language/reinterpret_cast and I noticed that it specifies the legal types we can always cast to:
byte*
char*
unsigned char*
But I did not see void*
in the list. Is this an oversight? My use case requires a reinterpret_cast
because I'm casting from an int**
to a void*
. And I will eventually cast from the void*
back to an int**
.
c++ pointers void-pointers reinterpret-cast double-pointer
I was looking at https://en.cppreference.com/w/cpp/language/reinterpret_cast and I noticed that it specifies the legal types we can always cast to:
byte*
char*
unsigned char*
But I did not see void*
in the list. Is this an oversight? My use case requires a reinterpret_cast
because I'm casting from an int**
to a void*
. And I will eventually cast from the void*
back to an int**
.
c++ pointers void-pointers reinterpret-cast double-pointer
c++ pointers void-pointers reinterpret-cast double-pointer
asked 10 hours ago
Jonathan MeeJonathan Mee
22.2k1066177
22.2k1066177
2
"it specifies the legal types we can always cast to" This seems like your invention. That page does not say anything similar to that.
– cpplearner
10 hours ago
1
You don't need areinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl
– Max Langhof
10 hours ago
I've reopened the question because I didn't see only the top answer applies to this. Leaving a link here: stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
– NathanOliver
10 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
10 hours ago
@FrançoisAndrieux Ugh, I knew that. I'm just forgetting like an idiot. Could you just post that as an answer and I'll accept?
– Jonathan Mee
10 hours ago
add a comment |
2
"it specifies the legal types we can always cast to" This seems like your invention. That page does not say anything similar to that.
– cpplearner
10 hours ago
1
You don't need areinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl
– Max Langhof
10 hours ago
I've reopened the question because I didn't see only the top answer applies to this. Leaving a link here: stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
– NathanOliver
10 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
10 hours ago
@FrançoisAndrieux Ugh, I knew that. I'm just forgetting like an idiot. Could you just post that as an answer and I'll accept?
– Jonathan Mee
10 hours ago
2
2
"it specifies the legal types we can always cast to" This seems like your invention. That page does not say anything similar to that.
– cpplearner
10 hours ago
"it specifies the legal types we can always cast to" This seems like your invention. That page does not say anything similar to that.
– cpplearner
10 hours ago
1
1
You don't need a
reinterpret_cast
to convert a pointer to void*
. godbolt.org/z/-eIfjl– Max Langhof
10 hours ago
You don't need a
reinterpret_cast
to convert a pointer to void*
. godbolt.org/z/-eIfjl– Max Langhof
10 hours ago
I've reopened the question because I didn't see only the top answer applies to this. Leaving a link here: stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
– NathanOliver
10 hours ago
I've reopened the question because I didn't see only the top answer applies to this. Leaving a link here: stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
– NathanOliver
10 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
10 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
10 hours ago
@FrançoisAndrieux Ugh, I knew that. I'm just forgetting like an idiot. Could you just post that as an answer and I'll accept?
– Jonathan Mee
10 hours ago
@FrançoisAndrieux Ugh, I knew that. I'm just forgetting like an idiot. Could you just post that as an answer and I'll accept?
– Jonathan Mee
10 hours ago
add a comment |
3 Answers
3
active
oldest
votes
Those types are exempt from strict aliasing rules. It does not mean they are the only type you can use with reinterpret_cast
. In the case of casting an object pointer to another object pointer type, failing to meet the requirements of strict aliasing rules means you cannot safely dereference the result. But you can still cast the resulting pointer back to the original type safely, and use the result as-if it was the original pointer.
The relevant section from cppreference on reinterpret_cast
:
(Any object pointer type
T1*
can be converted to another object pointer type cvT2*
. This is exactly equivalent tostatic_cast<cv T2*>(static_cast<cv void*>(expression))
(which implies that ifT2
's alignment requirement is not stricter thanT1
's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules)
When casting back to the original type, AliasedType
and DynamicType
are the same, so they are similar, which is the first case listed by the aliasing rules where it is legal to dereference the result of reinterpret_cast
:
Whenever an attempt is made to read or modify the stored value of an object of type
DynamicType
through a glvalue of typeAliasedType
, the behavior is undefined unless one of the following is true:
AliasedType
andDynamicType
are similar.
AliasedType
is the (possibly cv-qualified)signed
orunsigned
variant ofDynamicType
.
AliasedType
isstd::byte
, (since C++17)char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
add a comment |
[expr.reinterpret.cast]/7:
An object pointer can be explicitly converted to an object pointer of a different type.
[basic.compound]/3:
The type of a pointer to cv
void
or a pointer to an object type is called an object pointer type.
You don't need to use reinterpret_cast
, though. Every object pointer type whose pointed type is cv-unqualified is implicitly convertible to void*
, and the inverse can be done by static_cast
.
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
It is always legal to convert from a pointer to a type to a pointer to a different type including void, so if T is a type this is legal C++:
T* x;
void *y = reinterpret_cast<void *>(x);
In real world it is never used because void *
is a special case, and you obtain the same value with static_cast
:
void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast
(in fact above conversion is implicit and can be simply written void *y = x;
- thank to Michael Kenzel for noticing it)
To be more explicit the standard even says in draft n4659 for C++17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7
When a prvalue v of
object pointer type is converted to the object pointer type “pointer to cv T”, the result isstatic_cast<cv T*>(static_cast<cv void*>(v))
.
When you refer to byte and char being the only legal types, it is just that it is legal to dereference the converted pointer only for those types. void
is not included here because you can never dereference a void *
.
You don't even needstatic_cast
in your example. Any object pointer type is implicitly convertible tovoid*
(with equivalent cv qualifiers). You only needstatic_cast
to cast avoid*
back to an object pointer of a particular type…
– Michael Kenzel
9 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
, and back, which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
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%2f55728740%2fis-it-legal-to-reinterpret-cast-to-a-void%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Those types are exempt from strict aliasing rules. It does not mean they are the only type you can use with reinterpret_cast
. In the case of casting an object pointer to another object pointer type, failing to meet the requirements of strict aliasing rules means you cannot safely dereference the result. But you can still cast the resulting pointer back to the original type safely, and use the result as-if it was the original pointer.
The relevant section from cppreference on reinterpret_cast
:
(Any object pointer type
T1*
can be converted to another object pointer type cvT2*
. This is exactly equivalent tostatic_cast<cv T2*>(static_cast<cv void*>(expression))
(which implies that ifT2
's alignment requirement is not stricter thanT1
's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules)
When casting back to the original type, AliasedType
and DynamicType
are the same, so they are similar, which is the first case listed by the aliasing rules where it is legal to dereference the result of reinterpret_cast
:
Whenever an attempt is made to read or modify the stored value of an object of type
DynamicType
through a glvalue of typeAliasedType
, the behavior is undefined unless one of the following is true:
AliasedType
andDynamicType
are similar.
AliasedType
is the (possibly cv-qualified)signed
orunsigned
variant ofDynamicType
.
AliasedType
isstd::byte
, (since C++17)char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
add a comment |
Those types are exempt from strict aliasing rules. It does not mean they are the only type you can use with reinterpret_cast
. In the case of casting an object pointer to another object pointer type, failing to meet the requirements of strict aliasing rules means you cannot safely dereference the result. But you can still cast the resulting pointer back to the original type safely, and use the result as-if it was the original pointer.
The relevant section from cppreference on reinterpret_cast
:
(Any object pointer type
T1*
can be converted to another object pointer type cvT2*
. This is exactly equivalent tostatic_cast<cv T2*>(static_cast<cv void*>(expression))
(which implies that ifT2
's alignment requirement is not stricter thanT1
's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules)
When casting back to the original type, AliasedType
and DynamicType
are the same, so they are similar, which is the first case listed by the aliasing rules where it is legal to dereference the result of reinterpret_cast
:
Whenever an attempt is made to read or modify the stored value of an object of type
DynamicType
through a glvalue of typeAliasedType
, the behavior is undefined unless one of the following is true:
AliasedType
andDynamicType
are similar.
AliasedType
is the (possibly cv-qualified)signed
orunsigned
variant ofDynamicType
.
AliasedType
isstd::byte
, (since C++17)char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
add a comment |
Those types are exempt from strict aliasing rules. It does not mean they are the only type you can use with reinterpret_cast
. In the case of casting an object pointer to another object pointer type, failing to meet the requirements of strict aliasing rules means you cannot safely dereference the result. But you can still cast the resulting pointer back to the original type safely, and use the result as-if it was the original pointer.
The relevant section from cppreference on reinterpret_cast
:
(Any object pointer type
T1*
can be converted to another object pointer type cvT2*
. This is exactly equivalent tostatic_cast<cv T2*>(static_cast<cv void*>(expression))
(which implies that ifT2
's alignment requirement is not stricter thanT1
's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules)
When casting back to the original type, AliasedType
and DynamicType
are the same, so they are similar, which is the first case listed by the aliasing rules where it is legal to dereference the result of reinterpret_cast
:
Whenever an attempt is made to read or modify the stored value of an object of type
DynamicType
through a glvalue of typeAliasedType
, the behavior is undefined unless one of the following is true:
AliasedType
andDynamicType
are similar.
AliasedType
is the (possibly cv-qualified)signed
orunsigned
variant ofDynamicType
.
AliasedType
isstd::byte
, (since C++17)char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
Those types are exempt from strict aliasing rules. It does not mean they are the only type you can use with reinterpret_cast
. In the case of casting an object pointer to another object pointer type, failing to meet the requirements of strict aliasing rules means you cannot safely dereference the result. But you can still cast the resulting pointer back to the original type safely, and use the result as-if it was the original pointer.
The relevant section from cppreference on reinterpret_cast
:
(Any object pointer type
T1*
can be converted to another object pointer type cvT2*
. This is exactly equivalent tostatic_cast<cv T2*>(static_cast<cv void*>(expression))
(which implies that ifT2
's alignment requirement is not stricter thanT1
's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules)
When casting back to the original type, AliasedType
and DynamicType
are the same, so they are similar, which is the first case listed by the aliasing rules where it is legal to dereference the result of reinterpret_cast
:
Whenever an attempt is made to read or modify the stored value of an object of type
DynamicType
through a glvalue of typeAliasedType
, the behavior is undefined unless one of the following is true:
AliasedType
andDynamicType
are similar.
AliasedType
is the (possibly cv-qualified)signed
orunsigned
variant ofDynamicType
.
AliasedType
isstd::byte
, (since C++17)char
, orunsigned char
: this permits examination of the object representation of any object as an array of bytes.
edited 10 hours ago
answered 10 hours ago
François AndrieuxFrançois Andrieux
16.6k32950
16.6k32950
add a comment |
add a comment |
[expr.reinterpret.cast]/7:
An object pointer can be explicitly converted to an object pointer of a different type.
[basic.compound]/3:
The type of a pointer to cv
void
or a pointer to an object type is called an object pointer type.
You don't need to use reinterpret_cast
, though. Every object pointer type whose pointed type is cv-unqualified is implicitly convertible to void*
, and the inverse can be done by static_cast
.
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
[expr.reinterpret.cast]/7:
An object pointer can be explicitly converted to an object pointer of a different type.
[basic.compound]/3:
The type of a pointer to cv
void
or a pointer to an object type is called an object pointer type.
You don't need to use reinterpret_cast
, though. Every object pointer type whose pointed type is cv-unqualified is implicitly convertible to void*
, and the inverse can be done by static_cast
.
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
[expr.reinterpret.cast]/7:
An object pointer can be explicitly converted to an object pointer of a different type.
[basic.compound]/3:
The type of a pointer to cv
void
or a pointer to an object type is called an object pointer type.
You don't need to use reinterpret_cast
, though. Every object pointer type whose pointed type is cv-unqualified is implicitly convertible to void*
, and the inverse can be done by static_cast
.
[expr.reinterpret.cast]/7:
An object pointer can be explicitly converted to an object pointer of a different type.
[basic.compound]/3:
The type of a pointer to cv
void
or a pointer to an object type is called an object pointer type.
You don't need to use reinterpret_cast
, though. Every object pointer type whose pointed type is cv-unqualified is implicitly convertible to void*
, and the inverse can be done by static_cast
.
edited 10 hours ago
answered 10 hours ago
cpplearnercpplearner
5,77122342
5,77122342
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from an
int**
to a void*
which I believe does require a reinterpret_cast
?– Jonathan Mee
2 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from an
int**
to a void*
which I believe does require a reinterpret_cast
?– Jonathan Mee
2 hours ago
add a comment |
It is always legal to convert from a pointer to a type to a pointer to a different type including void, so if T is a type this is legal C++:
T* x;
void *y = reinterpret_cast<void *>(x);
In real world it is never used because void *
is a special case, and you obtain the same value with static_cast
:
void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast
(in fact above conversion is implicit and can be simply written void *y = x;
- thank to Michael Kenzel for noticing it)
To be more explicit the standard even says in draft n4659 for C++17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7
When a prvalue v of
object pointer type is converted to the object pointer type “pointer to cv T”, the result isstatic_cast<cv T*>(static_cast<cv void*>(v))
.
When you refer to byte and char being the only legal types, it is just that it is legal to dereference the converted pointer only for those types. void
is not included here because you can never dereference a void *
.
You don't even needstatic_cast
in your example. Any object pointer type is implicitly convertible tovoid*
(with equivalent cv qualifiers). You only needstatic_cast
to cast avoid*
back to an object pointer of a particular type…
– Michael Kenzel
9 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
, and back, which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
It is always legal to convert from a pointer to a type to a pointer to a different type including void, so if T is a type this is legal C++:
T* x;
void *y = reinterpret_cast<void *>(x);
In real world it is never used because void *
is a special case, and you obtain the same value with static_cast
:
void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast
(in fact above conversion is implicit and can be simply written void *y = x;
- thank to Michael Kenzel for noticing it)
To be more explicit the standard even says in draft n4659 for C++17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7
When a prvalue v of
object pointer type is converted to the object pointer type “pointer to cv T”, the result isstatic_cast<cv T*>(static_cast<cv void*>(v))
.
When you refer to byte and char being the only legal types, it is just that it is legal to dereference the converted pointer only for those types. void
is not included here because you can never dereference a void *
.
You don't even needstatic_cast
in your example. Any object pointer type is implicitly convertible tovoid*
(with equivalent cv qualifiers). You only needstatic_cast
to cast avoid*
back to an object pointer of a particular type…
– Michael Kenzel
9 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
, and back, which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
It is always legal to convert from a pointer to a type to a pointer to a different type including void, so if T is a type this is legal C++:
T* x;
void *y = reinterpret_cast<void *>(x);
In real world it is never used because void *
is a special case, and you obtain the same value with static_cast
:
void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast
(in fact above conversion is implicit and can be simply written void *y = x;
- thank to Michael Kenzel for noticing it)
To be more explicit the standard even says in draft n4659 for C++17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7
When a prvalue v of
object pointer type is converted to the object pointer type “pointer to cv T”, the result isstatic_cast<cv T*>(static_cast<cv void*>(v))
.
When you refer to byte and char being the only legal types, it is just that it is legal to dereference the converted pointer only for those types. void
is not included here because you can never dereference a void *
.
It is always legal to convert from a pointer to a type to a pointer to a different type including void, so if T is a type this is legal C++:
T* x;
void *y = reinterpret_cast<void *>(x);
In real world it is never used because void *
is a special case, and you obtain the same value with static_cast
:
void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast
(in fact above conversion is implicit and can be simply written void *y = x;
- thank to Michael Kenzel for noticing it)
To be more explicit the standard even says in draft n4659 for C++17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7
When a prvalue v of
object pointer type is converted to the object pointer type “pointer to cv T”, the result isstatic_cast<cv T*>(static_cast<cv void*>(v))
.
When you refer to byte and char being the only legal types, it is just that it is legal to dereference the converted pointer only for those types. void
is not included here because you can never dereference a void *
.
edited 9 hours ago
answered 10 hours ago
Serge BallestaSerge Ballesta
81.9k963136
81.9k963136
You don't even needstatic_cast
in your example. Any object pointer type is implicitly convertible tovoid*
(with equivalent cv qualifiers). You only needstatic_cast
to cast avoid*
back to an object pointer of a particular type…
– Michael Kenzel
9 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
, and back, which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
add a comment |
You don't even needstatic_cast
in your example. Any object pointer type is implicitly convertible tovoid*
(with equivalent cv qualifiers). You only needstatic_cast
to cast avoid*
back to an object pointer of a particular type…
– Michael Kenzel
9 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from anint**
to avoid*
, and back, which I believe does require areinterpret_cast
?
– Jonathan Mee
2 hours ago
You don't even need
static_cast
in your example. Any object pointer type is implicitly convertible to void*
(with equivalent cv qualifiers). You only need static_cast
to cast a void*
back to an object pointer of a particular type…– Michael Kenzel
9 hours ago
You don't even need
static_cast
in your example. Any object pointer type is implicitly convertible to void*
(with equivalent cv qualifiers). You only need static_cast
to cast a void*
back to an object pointer of a particular type…– Michael Kenzel
9 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from an
int**
to a void*
, and back, which I believe does require a reinterpret_cast
?– Jonathan Mee
2 hours ago
Thanks for a really detailed answer... unfortunately this is going a little different direction from my misunderstanding. As you can see from the last line of the question I'm trying to cast from an
int**
to a void*
, and back, which I believe does require a reinterpret_cast
?– Jonathan Mee
2 hours ago
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%2f55728740%2fis-it-legal-to-reinterpret-cast-to-a-void%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
2
"it specifies the legal types we can always cast to" This seems like your invention. That page does not say anything similar to that.
– cpplearner
10 hours ago
1
You don't need a
reinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl– Max Langhof
10 hours ago
I've reopened the question because I didn't see only the top answer applies to this. Leaving a link here: stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
– NathanOliver
10 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
10 hours ago
@FrançoisAndrieux Ugh, I knew that. I'm just forgetting like an idiot. Could you just post that as an answer and I'll accept?
– Jonathan Mee
10 hours ago