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!When 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 convince students of the implication truth values?
Can you use the Shield Master feat to shove someone before you make an attack by using a Readied action?
Dating a Former Employee
When was Kai Tak permanently closed to cargo service?
Do jazz musicians improvise on the parent scale in addition to the chord-scales?
Circuit to "zoom in" on mV fluctuations of a DC signal?
Is the Standard Deduction better than Itemized when both are the same amount?
Is it common practice to audition new musicians one-on-one before rehearsing with the entire band?
When a candle burns, why does the top of wick glow if bottom of flame is hottest?
Using audio cues to encourage good posture
Compare a given version number in the form major.minor.build.patch and see if one is less than the other
How to tell that you are a giant?
Would "destroying" Wurmcoil Engine prevent its tokens from being created?
Is safe to use va_start macro with this as parameter?
Maximum summed powersets with non-adjacent items
How could we fake a moon landing now?
Do square wave exist?
Why are both D and D# fitting into my E minor key?
Can an alien society believe that their star system is the universe?
Closed form of recurrent arithmetic series summation
Amount of permutations on an NxNxN Rubik's Cube
Is it cost-effective to upgrade an old-ish Giant Escape R3 commuter bike with entry-level branded parts (wheels, drivetrain)?
Why are the trig functions versine, haversine, exsecant, etc, rarely used in modern mathematics?
Is it ethical to give a final exam after the professor has quit before teaching the remaining chapters of the course?
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!When 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
14 hours ago
1
You don't need areinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl
– Max Langhof
14 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
14 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
13 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
13 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 14 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
14 hours ago
1
You don't need areinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl
– Max Langhof
14 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
14 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
13 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
13 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
14 hours ago
1
You don't need areinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl
– Max Langhof
14 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
14 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
13 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
13 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
14 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
14 hours ago
1
1
You don't need a
reinterpret_cast
to convert a pointer to void*
. godbolt.org/z/-eIfjl– Max Langhof
14 hours ago
You don't need a
reinterpret_cast
to convert a pointer to void*
. godbolt.org/z/-eIfjl– Max Langhof
14 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
14 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
14 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
13 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
13 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
13 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
13 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
6 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
13 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
6 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 13 hours ago
answered 13 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
6 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
6 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 13 hours ago
answered 13 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
6 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
6 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
6 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
6 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
13 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
6 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
13 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
6 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 13 hours ago
answered 13 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
13 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
6 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
13 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
6 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
13 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
13 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
6 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
6 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
-c++, double-pointer, pointers, reinterpret-cast, void-pointers
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
14 hours ago
1
You don't need a
reinterpret_cast
to convert a pointer tovoid*
. godbolt.org/z/-eIfjl– Max Langhof
14 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
14 hours ago
@cpplearner The types are in the Type Aliasing section.
– Jonathan Mee
13 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
13 hours ago