Jump to content
  • Advertisement
Sign in to follow this  
Ryan_001

C++, casting and const

This topic is 3034 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can I use reinterpret_cast to add or remove const-ness? Now I know const_cast can, but more specifically is something like the following kosher?


void PrintInt (const void* p) {
cout << *reinterpret_cast<const int*>(p) << endl;
}

int a = 5;
const int b = 6;
PrintInt(&a);
PrintInt(&b);


From what I understand, reinterpret_cast is only valid if you cast the pointer back to its original type, but does the const modifier play into this (and what about volatile)? The above code example works in MSVC, but just cause it works doesn't mean its proper C++.

Share this post


Link to post
Share on other sites
Advertisement
Adding const doesn't require any sort of cast. reinterpret_cast can't remove const; a const_cast is required.

Share this post


Link to post
Share on other sites
Beware that casting to or from void* is almost never a good idea since it completely chucks type safety out the window.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ryan_001
Can I use reinterpret_cast to add or remove const-ness? Now I know const_cast can, but more specifically is something like the following kosher?


void PrintInt (const void* p) {
cout << *reinterpret_cast<const int*>(p) << endl;
}

int a = 5;
const int b = 6;
PrintInt(&a);
PrintInt(&b);


From what I understand, reinterpret_cast is only valid if you cast the pointer back to its original type, but does the const modifier play into this (and what about volatile)? The above code example works in MSVC, but just cause it works doesn't mean its proper C++.

As pointed out reinterpret_cast is the wrong operator to use here and Sicrane has already pointed out const_cast but that may require using along with static_cast. Currently your code is undefined/implementation specific; reinterpret_cast is rather limited in what it guarantees and allows.

Quote:
but does the const modifier play into this (and what about volatile)?

With respect to the void pointer, no this does not have any effect but it does have an effect for the type before it was implicitly cast to void const*. You are not casting back to the orignal type.

Don't use void pointer unless you must, I see no reason to use it here as the following does what you want.

std::cout <<(&type) <<std::endl;



Share this post


Link to post
Share on other sites
Quote:
Original post by Red Ant
Beware that casting to or from void* is almost never a good idea since it completely chucks type safety out the window.


Uhm. All casts throw away type safety. That's it's purpose in life. To throw away the type safety of the language because *you know better*.... ;)

Share this post


Link to post
Share on other sites
Anything you do via static_cast in C++ does not throw away type safety (in general it's just there to avoid a warning).

Anything you do via const_cast does not throw away type safety (provided you can guarantee the data is never written to, so for example a compatibility layer with C code can use it).

dynamic_cast does not throw away type safety (and cannot work with a void* pointer to begin with).

The only place where type safety goes out the window is the dreaded reinterpret_cast.

Share this post


Link to post
Share on other sites
Quote:
Original post by CmpDev
As pointed out reinterpret_cast is the wrong operator to use here and Sicrane has already pointed out const_cast but that may require using along with static_cast.


No he didn't. He said const_cast is required to remove const. Since this case doesn't require the removal of const, the correct cast would be static_cast.

Quote:
Original post by CmpDev
Currently your code is undefined/implementation specific; reinterpret_cast is rather limited in what it guarantees and allows.


Uhm, reinterpret_cast has no limitations. It's the most limitation free of all the casts. It's not undefined behaviour either, quite the opposite infact... There will be an integer at the memory location referenced by p (although care has to be taken to ensure you use the function correctly since it's without type checking).

Quote:
Original post by CmpDev
Quote:
but does the const modifier play into this (and what about volatile)?

With respect to the void pointer, no this does not have any effect but it does have an effect for the type before it was implicitly cast to void const*. You are not casting back to the orignal type.


void const* and const void* are not the same types. volatile does not come into play here (and won't do unless you start using multiple threads).

Quote:
Original post by CmpDev
Don't use void pointer unless you must, I see no reason to use it here as the following does what you want.
*** Source Snippet Removed ***


Lol. It's definitely not what he wants....

Share this post


Link to post
Share on other sites
Quote:
Original post by BitMaster
Anything you do via static_cast in C++ does not throw away type safety (in general it's just there to avoid a warning).


Nonsense. It throws away type safety.


class Foo
{
};
class Bar : public Foo
{
float a;
};
class Car : public Foo
{
int a;
};

Foo* f = new Bar();
Car* c = static_cast<Car*>(f);




Quote:
Original post by BitMaster
Anything you do via const_cast does not throw away type safety (provided you can guarantee the data is never written to, so for example a compatibility layer with C code can use it).


removing const is *only* ever needed when you need to write to the variable (otherwise you wouldn't need to get rid of const). const is part of C by the way (just have a look in gl.h, stdlib.h). So by removing the const you are throwing away the type safety (since a programmer will assume that const args passed to a function will not be modified).

Quote:
Original post by BitMaster
dynamic_cast does not throw away type safety (and cannot work with a void* pointer to begin with).


True, but I prefer to pretend that one doesn't exist (there are better ways to perform RTTI that don't require tonnes of strcmps). All games will have RTTI disabled...

Quote:
The only place where type safety goes out the window is the dreaded reinterpret_cast.


And static cast, and const cast, and the C cast (re-interpret under a different name).

Share this post


Link to post
Share on other sites
Quote:
Original post by RobTheBloke
Quote:
Original post by CmpDev
As pointed out reinterpret_cast is the wrong operator to use here and Sicrane has already pointed out const_cast but that may require using along with static_cast.


No he didn't. He said const_cast is required to remove const. Since this case doesn't require the removal of const, the correct cast would be static_cast.

I do not know what you are disagreeing with here, reinterpret_cast is the wrong one to use.
Quote:
Original post by RobTheBloke
Quote:
Original post by CmpDev
Currently your code is undefined/implementation specific; reinterpret_cast is rather limited in what it guarantees and allows.


Uhm, reinterpret_cast has no limitations. It's the most limitation free of all the casts. It's not undefined behaviour either, quite the opposite infact... There will be an integer at the memory location referenced by p (although care has to be taken to ensure you use the function correctly since it's without type checking).

IIRC reinterpret_cast has the least set of circumstances which is defined, any type of cast not mentioned in the standard is either UB or IS. Cast from one pointer type to void pointer and then to a different pointer is not defined at best is IS.

Quote:
Original post by RobTheBloke
Quote:
Original post by CmpDev
Quote:
but does the const modifier play into this (and what about volatile)?

With respect to the void pointer, no this does not have any effect but it does have an effect for the type before it was implicitly cast to void const*. You are not casting back to the orignal type.


void const* and const void* are not the same types.
[/quote]
Ok you have lost me here they are the same!
Quote:
Original post by RobTheBloke
volatile does not come into play here (and won't do unless you start using multiple threads).

volatile has nothing todo with threads but that is another topic.

Quote:
Original post by RobTheBloke
Quote:
Original post by CmpDev
Don't use void pointer unless you must, I see no reason to use it here as the following does what you want.
*** Source Snippet Removed ***


Lol. It's definitely not what he wants....


I hold my hand up for that small mistake, I could laugh at the many you have just written.

Share this post


Link to post
Share on other sites
Quote:
Original post by RobTheBloke
void const* and const void* are not the same types.

Just wanted to make the one comment that these are in fact exactly the same type, and that "void * const" would probably be the different type you're thinking of.

Edit: For reference http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.9

Edit2: Okay, this too...
Quote:
Original post by CmpDev
volatile has nothing todo with threads but that is another topic.

This isn't true either. Volatile specifically says "other threads/processes may modify this" so that the compiler won't screw things up with optimizations.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!