• Advertisement
Sign in to follow this  

reinterpret_cast examples?

This topic is 1725 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

No, with multiple inheritance the reinterpret_cast will just cast the pointer, but static_cast will correctly adjust the pointer for the different base classes. Base and derived types are related, so you use static_cast which is used to cast between related types.

 

That's the difference between the two that I hinted at earlier; reinterpret_cast will just cast the type, but static_cast will also cast the value if necessary.

Share this post


Link to post
Share on other sites
Advertisement

Now you can address the pixels on that scan.

With the caveat that the memory must be properly aligned.

 

The x86 family is almost unique that it will allow misaligned integer access.  There is a nasty performance penalty for each read.  

 

Most systems will simply crash on that line if you aren't lucky enough to have a correct alignment.

Fantastic point! That is very easy for me to forget sometimes. (Though the user may very well have considered this when allocating their image).

Share this post


Link to post
Share on other sites

No, with multiple inheritance the reinterpret_cast will just cast the pointer, but static_cast will correctly adjust the pointer for the different base classes. Base and derived types are related, so you use static_cast which is used to cast between related types.

 

That's the difference between the two that I hinted at earlier; reinterpret_cast will just cast the type, but static_cast will also cast the value if necessary.

 

Ok,but isn't changing just the type enough? I mean it's a pointer,not an object.

Share this post


Link to post
Share on other sites

No, changing the type is not enough.

struct base1 { };
struct base2 { };
struct derived : base1, base2 { };

int main(int, char**)
{
    base2 *b = new derived;
    base1 *br = reinterpret_cast<derived *>(b);
    base1 *bs = static_cast<derived *>(b);

    std::cout << b << std::endl;
    std::cout << br << std::endl;
    std::cout << bs << std::endl;
}

Here, b is a base2-pointer to a derived object, and br and bs are base1-pointers to the derived object typecast via the derived class using reinterpret_cast and static_cast, respectively.

 

The br pointer is an invalid cast because you have a base1 pointer incorrectly pointing to the base2 subclass of the derived object. The bs pointer is a valid pointer because you have a base1 pointer correctly pointing to the base1 subclass of the derived object.

 

Try the program, the two last pointers should be different. The cast requires changing the pointer's value as well as changing its type.

Share this post


Link to post
Share on other sites

AFAIK (I am not a language lawyer) the only thing you can safely do after having performed a reinterpret_cast is to cast back again with another reinterpret_cast.

So you could not cast and then use the value for anything because it's implementation defined - in practice specific implementations make useful guarantees about things, but the C++ standard doesn't.

 

So a standards-compliant practical use of reinterpret_cast would be to pass a T* pointer through an API that only accepts, say, a void* or a char*. Then on the other side, you can cast it back to a T*.

 

I'd be interested to know if the standard does offer any additional guarantees?

In any case, use of reinterpret_cast makes me nervous.

Share this post


Link to post
Share on other sites
Other than converting back to the original type, the standard also says that if you convert a null pointer of one type to another pointer type the result will be a null pointer of the new type, so you can check a reinterpret_cast'ed pointer for null. A reinterpret_cast on things like integers and pointers to their own type will also yield the value of the original operand. Pretty much everything is either undefined, unspecified or implementation defined.

Share this post


Link to post
Share on other sites

Well, a C-style cast trumps everything (can do all types of casts).

That is actually not true. It cannot do casts of pointer to classes with multiple inheritance in some cases. The C-style cast will just reinterpret the pointer value, but a proper C++ style cast may actually change the value to handle multiple inheritance correctly.

As far as I know, C-style cast in C++ is defined to try to do a static cast, and if it can't, then do a reinterpret cast. So it should handle multiple inherritance fine. However, if you have a bug and you're doing something where it is not possible to do the cast as a static cast, then the C-style cast will do a reinterpret cast, hiding the bug.

 

There's also constructor-style cast, which works just like C-style cast, except when it calls a constructor.

Share this post


Link to post
Share on other sites

 

Well, a C-style cast trumps everything (can do all types of casts).

That is actually not true. It cannot do casts of pointer to classes with multiple inheritance in some cases. The C-style cast will just reinterpret the pointer value, but a proper C++ style cast may actually change the value to handle multiple inheritance correctly.

As far as I know, C-style cast in C++ is defined to try to do a static cast, and if it can't, then do a reinterpret cast. So it should handle multiple inherritance fine. However, if you have a bug and you're doing something where it is not possible to do the cast as a static cast, then the C-style cast will do a reinterpret cast, hiding the bug.

I have already discussed the ambiguous nature of the type of cast the C-style cast performs and why it doesn't work with multiple inheritance in some cases. It is because it silently falls back on the incorrect reinterpret_cast that it is dangerous to use.

Share this post


Link to post
Share on other sites




Well, a C-style cast trumps everything (can do all types of casts).

That is actually not true. It cannot do casts of pointer to classes with multiple inheritance in some cases. The C-style cast will just reinterpret the pointer value, but a proper C++ style cast may actually change the value to handle multiple inheritance correctly.


As far as I know, C-style cast in C++ is defined to try to do a static cast, and if it can't, then do a reinterpret cast. So it should handle multiple inherritance fine. However, if you have a bug and you're doing something where it is not possible to do the cast as a static cast, then the C-style cast will do a reinterpret cast, hiding the bug.


I have already discussed the ambiguous nature of the type of cast the C-style cast performs and why it doesn't work with multiple inheritance in some cases. It is because it silently falls back on the incorrect reinterpret_cast that it is dangerous to use.


You discussed why reinterpret_cast does not work with multiple inheritance. C-style cast isn't reinterpret_cast though. It tries to do a static cast first, so correctly written multiple inherritance will work with it.

Yes, C-style casts are bad, but not because of multiple inherritance.

Share this post


Link to post
Share on other sites

I also said, and so did you, that C-style cast will do a reinterpret_cast if it cannot do the static_cast. When reinterpret_cast is the wrong thing to do in those cases, then so is the C-style that incorrectly proceeds with the cast. It changes the behavior of the cast, and the casting behavior between the two is different in multiple inheritance.

Share this post


Link to post
Share on other sites

just my humble opinion: everyone should use the c++ explicit casts.It doesn't matter if you're doing a static cast,or a reinterpret cast.If you ever have problems,it will be a lot easier to locate the casts and recognize fast what kind of cast you are doing.

 

 

@Brother Bob,you made a wonderful example showing me why I should use static_cast when the types are releated.Kudos!

Edited by noatom

Share this post


Link to post
Share on other sites

That is the correct answer. C-style casts being difficult to search (find in files, grep) for, and a cause of bugs, is my main gripe with them.

Share this post


Link to post
Share on other sites

Well,Cornstalks,that's an amazing resource,thanks for sharing.

Share this post


Link to post
Share on other sites

I also said, and so did you, that C-style cast will do a reinterpret_cast if it cannot do the static_cast. When reinterpret_cast is the wrong thing to do in those cases, then so is the C-style that incorrectly proceeds with the cast. It changes the behavior of the cast, and the casting behavior between the two is different in multiple inheritance.

The behavior of a c-style cast is always the same as a static cast, when a static cast is possible, which is is when upcasting multiple ingerritance. So the C cast will correctly upcast.

When static_cast doesn't work, reinterpret cast is probably not wrong; it's the only option. However, it might hide a bug where you expect static cast to be possible, but it isn't. The bug is likely elsewhere, but using static_cast may help catch it, turning a runtime error into a compile time error. But again, this has little to do with multiple inherritance. Edited by King Mir

Share this post


Link to post
Share on other sites

Yes, you have said that a few times, and so have I. I know that the C-style case will do the right thing when static_cast can do its job. When static_cast is not working, for example you have only forward declared your classes and not fully defined the inheritance tree to the point you want to cast, then reinterpret_cast, and consequently also the C-style cast, will do the wrong thing. I have already stated this earlier in this thread.

Share this post


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

  • Advertisement