Casting pointers

T

Taras_96

Hi everyone,

Herb Schildt in "C++, the complete reference" writes:

"In C++, it is illegal to convert one type of pointer into another
without the use of an
explicit type cast. For this reason, the preceding program will not
even compile if
you try to compile it as a C++ (rather than as a C) program. However,
the type of
error described can still occur in C++ in a more roundabout manner."

However, the following works with g++ without any errors:

Derived* pDerived = new Derived();
Base* pBase = pDerived;

What was Herb referring to when he said it is illegal to cast from one
type to another (possibly he meant from one class to an unrelated
class, or from an int to a float)

Taras
 
M

Michael DOUBEZ

Krice a écrit :
When you need a cast it's a sign of bad design.

Where have you seen that ?
The use of static_cast<>() is fairly common and secure.

The only cast that can yield UB are const_cast<>() and
reinterpret_cast<>() (and of course old C cast style) and they should be
used with care.
 
R

red floyd

Taras_96 said:
Hi everyone,

Herb Schildt in "C++, the complete reference" writes:

Stop right there. Ignore *ANYTHING* you read in that book. Take the
book outside and burn it immediately.
 
R

Richard Herring

Michael DOUBEZ said:
Krice a écrit :

Where have you seen that ?
The use of static_cast<>() is fairly common and secure.

Not always. You can use static_cast to downcast from Base* to Derived*,
for example, but at that point you're telling the compiler you know
better than it does, so you'd better be very sure you really are
pointing to a Derived, or ...
 
R

Rolf Magnus

Taras_96 said:
Hi everyone,

Herb Schildt in "C++, the complete reference" writes:

This book is known for having quite some errors.
"In C++, it is illegal to convert one type of pointer into another
without the use of an explicit type cast.

That is incorrect.
However, the following works with g++ without any errors:

Derived* pDerived = new Derived();
Base* pBase = pDerived;

Yes, assuming that Derived is a class derived from Base, this code is
correct. This should also work:

void* p = pDerived;
What was Herb referring to when he said it is illegal to cast from one
type to another (possibly he meant from one class to an unrelated
class, or from an int to a float)

Who knows? I would recommend to get a better book.
 
J

Juha Nieminen

Taras_96 said:
Hi everyone,

Herb Schildt in "C++, the complete reference" writes:

"In C++, it is illegal to convert one type of pointer into another
without the use of an
explicit type cast. For this reason, the preceding program will not
even compile if
you try to compile it as a C++ (rather than as a C) program. However,
the type of
error described can still occur in C++ in a more roundabout manner."

However, the following works with g++ without any errors:

Derived* pDerived = new Derived();
Base* pBase = pDerived;

Well, an object of type Derived *is* an object of type Base. Basic
object-oriented programming.
 
R

Rolf Magnus

Juha said:
Well, an object of type Derived *is* an object of type Base. Basic
object-oriented programming.

However, an object of type pointer to Derived is *not* an object of type
pointer to Base.
 
S

Sergey Prokazov

Hi everyone,

Herb Schildt in "C++, the complete reference" writes:

"In C++, it is illegal to convert one type of pointer into another
without the use of an
explicit type cast. For this reason, the preceding program will not
even compile if
you try to compile it as a C++ (rather than as a C) program. However,
the type of
error described can still occur in C++ in a more roundabout manner."

However, the following works with g++ without any errors:

Derived* pDerived = new Derived();
Base* pBase = pDerived;

What was Herb referring to when he said it is illegal to cast from one
type to another (possibly he meant from one class to an unrelated
class, or from an int to a float)

Taras

This kind of casting is called "upcasting". As far as derived class
supports all public functionality of the base class, this kind of
casting is safe and explicit casting is not necessary. But I think
it's a good style if you use static_cast<>() for upcasting. For
downcasting and cross-casting you should use dynamic_cast<>(), but
frankly, these kinds of casting almost always point to bad design.
 
J

Juha Nieminen

Rolf said:
However, an object of type pointer to Derived is *not* an object of type
pointer to Base.

But since the objects they are pointing to are "of the same type", the
casting is valid (although only in the Derived -> Base direction).
 
J

James Kanze

Krice a écrit :
Where have you seen that ?
The use of static_cast<>() is fairly common and secure.
The only cast that can yield UB are const_cast<>() and
reinterpret_cast<>() (and of course old C cast style) and they
should be used with care.

Are you saying that:

float* pf ;
MyClass* pc = static_cast< MyClass* >(
static_cast< void* >( pf ) ) ;

is "secure"?

Generally, the only pointer cast that is "common and secure" is
dynamic_cast (and it's not that common). static_cast is "common
and secure" for non-pointer types, in specific circumstances,
e.g.:

int a, b ;
double c = static_cast< double >( a ) + b ;

(In this particular case, I'd still use a C style cast:).) And
of course, all casts have their uses in special cases.
 
M

Michael DOUBEZ

Richard Herring a écrit :
Not always. You can use static_cast to downcast from Base* to Derived*,
for example, but at that point you're telling the compiler you know
better than it does, so you'd better be very sure you really are
pointing to a Derived, or ...

If you use static_cast<>() in this case, the compiler will issue an
error (unless it has information saying it is safe.

Example:
struct A{};
struct B: public A{};
struct C: public A{};

int main()
{
B b;
A* a=&b;
B* ba=static_cast<B*>(a); //OK

B* bp=a; //error
C*c=static_cast<B*>(a);//error
}

Michael
 
M

Michael DOUBEZ

James Kanze a écrit :
Are you saying that:

float* pf ;
MyClass* pc = static_cast< MyClass* >(
static_cast< void* >( pf ) ) ;

is "secure"?

Yes. I forgot 'void*' but it is then the equivalent of a
Generally, the only pointer cast that is "common and secure" is
dynamic_cast (and it's not that common). static_cast is "common
and secure" for non-pointer types, in specific circumstances,
e.g.:

int a, b ;
double c = static_cast< double >( a ) + b ;

(In this particular case, I'd still use a C style cast:).) And
of course, all casts have their uses in special cases.

Agreed. The point was mainly to show that the usage of cast is not a
sign of bad design.

It is funny to see that the only 100% secure cast (i.e.
dynamic_cast<>()) is the one the most associated with bad design.
 
R

Rolf Magnus

Juha said:
But since the objects they are pointing to are "of the same type", the
casting is valid (although only in the Derived -> Base direction).

The sentence that we're discussing about is: "In C++, it is illegal to
convert one type of pointer into another without the use of an
explicit type cast". And that is wrong. In the above example, the pointers
are of different type, and still they can be converted without a cast.
 
T

Taras_96

Who knows? I would recommend to get a better book.

Does anyone have any recommendations? I personally find Bjarne
Stroustrup's a bit too technical for a beginner (it serves better as a
reference).

Taras
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,610
Members
45,254
Latest member
Top Crypto TwitterChannel

Latest Threads

Top