error for reinterpret_cast BUT no error for C-style cast?

Started by
4 comments, last by ToohrVyk 16 years, 3 months ago
This has happened to me a few times recently. I wish I had a concrete example for a reproducable case, but I currently don't. I have some pseudocode though. Wondering if it's happened to you (and why a C-style cast takes away the compiler error.) [C++, VS2005 Pro]

const MyMat33* pMat = (reinterpret_cast<const Mat33*>( &instance->GetMat() ));

// error C2440: '=' : cannot convert from 'const Mat33 *' to 'const MyMat33 *'
// Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast




Where instance->GetMat() returns a const reference to a Mat33. And I want to assign its address to a MyMat33 pointer. As mentioned, switching to C-style cast fixed the problem. But why?

const MyMat33* pMat = (const MyMat33*)( &instance->GetMat() );




I mean, it's telling me to use a reinterpret_cast<>(), and I am!! [Edited by - discman1028 on January 10, 2008 12:57:13 PM]
--== discman1028 ==--
Advertisement
Quote:I wish I had a concrete example for a reproducable case, but I currently don't.

This is almost always the first step. Your use of the word "psuedocode" worries me.

Mat33 and MyMat33 are very similar names. Any chance you're doing something like this?

const MyMat33* pMat = (reinterpret_cast<const Mat33*>( &instance->GetMat() ));

That is, reinterpret_cast<>ing to the wrong type? I ask this because it seems to be refering to the assignment, not the cast itself.

If this was the case, I suggest you actually copy & paste such problematic lines in the future, even if you're not providing all the contextual source. It avoids accidentally fixing the issue without realizing it.

I cannot reproduce your problem on VS2008 -- the following snippet does not exhibit your problem with the exact same line:

struct Mat33 {};struct MyMat33 {};struct HasAMat33 {	const Mat33& GetMat();};int main() {	HasAMat33* instance;	const MyMat33* pMat = (reinterpret_cast<const MyMat33*>( &instance->GetMat() ));}


This snippet compiles, although obviously won't link, nor run without undefined behavior.
Quote:Original post by MaulingMonkey

const MyMat33* pMat = (reinterpret_cast<const Mat33*>( &instance->GetMat() ));



My mistake... the error should have matched up with the source (fixed now). In any case, I mean to ask the general question: has anyone ever gotten a compile error with reinterpret cast, and fixed it by using a C-style cast instead?

I will follow up with an example the next time I hit a concrete repro case.
--== discman1028 ==--
reinterpret_cast (and C-style cast) are the unsafest casts. In your case, using it to convert between unrelated (?) classes seems rather suspicious. You can cast apples into oranges but you shouldn't expect anything good from it.

As to where reinterpret_cast would fail is casting away constness:
int main(){    double a = 42;    const double* d = &a;    int* q = (int*)d;    int* p = reinterpret_cast<int*>(d);    }
Quote:Original post by discman1028
Quote:Original post by MaulingMonkey

const MyMat33* pMat = (reinterpret_cast<const Mat33*>( &instance->GetMat() ));



My mistake... the error should have matched up with the source (fixed now).


What do you mean by that?

What MaulingMonkey has bolded in that line shows that you are casting the value returned by GetMat() into a Mat33, but attempting to store it in a MyMat33.

To cast a Mat33 returned by GetMat() into a MyMat33, you should be using:
const MyMat33* pMat = (reinterpret_cast<const MyMat33>(&instance->GetMat()));

Is your original code using Mat33 or MyMat33 there?
Quote:Original post by discman1028
My mistake... the error should have matched up with the source (fixed now). In any case, I mean to ask the general question: has anyone ever gotten a compile error with reinterpret cast, and fixed it by using a C-style cast instead?


Partially. There are situations where using reinterpret_cast causes an error and C-style casts don't. For example:
char foo[] = "Hello";const char *a = foo;char *b = reinterpret_cast<char*>(foo); // Errorchar *c = (char*) foo; // Works


However, this is a typical situation of the C-style cast representing a cast mode that isn't covered by reinterpret-casting (in this particular case, const-casting). It's usually a sign that you should be using another C++ cast (or several):
char *d = const_cast<char*>(foo); // Works 


This topic is closed to new replies.

Advertisement