By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 1,023 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

static_cast vs reinterpert_cast

P: n/a
Hi,

I have a
class A : public B {...member functions......data members};

and am doing the following
A *p=new A();
void *p=static_cast<void *>(p);
factory_instance->process(p);

Here p is passed to a function, which accepts void ptr. That function
need to cast it back
A *pp=static_cast<A *>(p);

The function is in the factory which accepts void *p only, the specific
implementations need to cast the pointer back to the expected class
and use it.

Question:Though both works fine, yet I want to know what is more
appropriate in this situation static_cast OR reinterpert_cast

The books suggests
static_cast= "For "well-behaved" and "reasonably
well-behaved" casts,including things you might now do without a cast
reinterpret_cast=To cast to a completely different meaning. The key
is that you'll need to cast back to the original type to use it
safely.

But I am not able to interpret the sentences in this context :-)

Jul 10 '06 #1
Share this Question
Share on Google+
24 Replies


P: n/a

Rahul wrote:
>
and am doing the following
A *p=new A();
void *p=static_cast<void *>(p);
factory_instance->process(p);

Here p is passed to a function, which accepts void ptr. That function
need to cast it back
A *pp=static_cast<A *>(p);
Don't cast to void* before calling process(), it's not needed and the
less casts you have the better - just pass the A* as is like this:
A* pa = new A();
factory_instance->process(pa);
Casting back to A* inside process() should be fine.
It'd obviously be better if process() took an A* (or some Base-of-A*)
in the first place.

Jul 10 '06 #2

P: n/a
Rahul wrote:
Hi,

I have a
class A : public B {...member functions......data members};

and am doing the following
A *p=new A();
void *p=static_cast<void *>(p);
factory_instance->process(p);

Here p is passed to a function, which accepts void ptr.
No need for a static_cast. You can convert a pointer to an object into a
pointer to void implicitly.
That function
need to cast it back
A *pp=static_cast<A *>(p);

The function is in the factory which accepts void *p only, the specific
implementations need to cast the pointer back to the expected class
and use it.

Question:Though both works fine, yet I want to know what is more
appropriate in this situation static_cast OR reinterpert_cast
static_cast. Generally, one could say that you should choose static_cast
over reinterpret_cast if it does the job.
The books suggests
static_cast= "For "well-behaved" and "reasonably
well-behaved" casts,including things you might now do without a cast
reinterpret_cast=To cast to a completely different meaning. The key
is that you'll need to cast back to the original type to use it
safely.

But I am not able to interpret the sentences in this context :-)
You could translate it to "reinterpret_cast is more evil than
static_cast" ;-)

Jul 10 '06 #3

P: n/a
Hi,

static_cast is meant to be used for cases which the compiler would
automatically be able to convert, such as char to int and in your case
A* to void*. reinterpret_cast is used, as the book mentions, for
low-level hacks, especially when you know what you are doing, eg:

struct S
{
int a, b;
};

int main()
{
S s;
s.a = 10;
s.b = 20;

int* p = reinterpret_cast<int*>(&s);
cout << "a=" << *p << endl;
++p;
cout << "b=" << *p << endl;
}

Typically reinterpret_cast should work where a static_cast works.
"Ideally" in C++ we should avoid using void* as much because we loose
type safety. Also in your case you do seem to be having a class
hierarchy (A,B), so using virtual functions with base ptrs would be
cleaner (if virtual fn overhead is not an issue).

Thanks and regards
Sonison James

Rahul wrote:
Hi,

I have a
class A : public B {...member functions......data members};

and am doing the following
A *p=new A();
void *p=static_cast<void *>(p);
factory_instance->process(p);

Here p is passed to a function, which accepts void ptr. That function
need to cast it back
A *pp=static_cast<A *>(p);

The function is in the factory which accepts void *p only, the specific
implementations need to cast the pointer back to the expected class
and use it.

Question:Though both works fine, yet I want to know what is more
appropriate in this situation static_cast OR reinterpert_cast

The books suggests
static_cast= "For "well-behaved" and "reasonably
well-behaved" casts,including things you might now do without a cast
reinterpret_cast=To cast to a completely different meaning. The key
is that you'll need to cast back to the original type to use it
safely.

But I am not able to interpret the sentences in this context :-)
Jul 10 '06 #4

P: n/a
Rahul wrote:
The books suggests
static_cast= "For "well-behaved" and "reasonably
well-behaved" casts,including things you might now do without a cast
reinterpret_cast=To cast to a completely different meaning. The key
is that you'll need to cast back to the original type to use it
safely.
If your books say that, burn them. That's not the definition of
static cast.

There are two meanings for static cast:

1. Forcing conversions that could happen anyway:

static_cast<int>(5.5)

2. With the exception of const conversions, reversing defined conversions:
class B { };
class D : public B { };

B* b = new D; // defined conversion D* ->B*
D* d = static_cast<B*>(b);

It is still incumbent on the application to determine the
validity of the second time type of cast. In this case
making sure that b contains an value that really is
convertable to D*.
Jul 10 '06 #5

P: n/a


I have a simple rule-of-thumb:

If you can use static_cast, then use static_cast.

If you can't use static_cast, then use reinterpret_cast.
--

Frederick Gotham
Jul 10 '06 #6

P: n/a
Frederick Gotham wrote:
I have a simple rule-of-thumb:

If you can use static_cast, then use static_cast.

If you can't use static_cast, then use reinterpret_cast.
I have a simple preceding rule:

If you can do it without a cast, do not use any cast.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 10 '06 #7

P: n/a
Victor Bazarov posted:
Frederick Gotham wrote:
>I have a simple rule-of-thumb:

If you can use static_cast, then use static_cast.

If you can't use static_cast, then use reinterpret_cast.

I have a simple preceding rule:

If you can do it without a cast, do not use any cast.
Naturally ; )
I tend to use the old-style casts now and again too, e.g.:

enum { len = 64U };

int array[len];

for(size_t i = len - 1; (size_t)-1 != i; --i)
Or if I need a reinterpret_cast and a const_cast at the same time:

char const *pc = 0;

int *pi = (int*)pc;

/* A very contrived example, I realise! */
The major drawback of the new-style casts is that they take up far too much
horizontal screen space.
--

Frederick Gotham
Jul 10 '06 #8

P: n/a
dio
Frederick Gotham <fg*******@SPAM.comwrote:
The major drawback of the new-style casts is that they take up far too much
horizontal screen space.
Yes, which should serve as a visual reminder that a design that relies
heavily on casts is perhaps not ideal.

--
like a rainbow in the dark.
Jul 10 '06 #9

P: n/a
dio posted:
Frederick Gotham <fg*******@SPAM.comwrote:
>The major drawback of the new-style casts is that they take up far too
much horizontal screen space.

Yes, which should serve as a visual reminder that a design that relies
heavily on casts is perhaps not ideal.

I'm out of nappies now though, and I can judge sensibly as to when I should
use what kind of cast. Would you prefer:

int *p = reinterpret_cast<int*>(
const_cast<char*>(pcc)
);

or:

int *p = (char*)pcc;
And,
size_t i = static_cast<size_t>(-1);

or:

size_t i = (size_t)-1;
(Second example is intended to supress a compiler warning)
--

Frederick Gotham
Jul 10 '06 #10

P: n/a
Frederick Gotham wrote:
dio posted:

>>Frederick Gotham <fg*******@SPAM.comwrote:
>>>The major drawback of the new-style casts is that they take up far too
much horizontal screen space.

Yes, which should serve as a visual reminder that a design that relies
heavily on casts is perhaps not ideal.

I'm out of nappies now though, and I can judge sensibly as to when I should
use what kind of cast. Would you prefer:

int *p = reinterpret_cast<int*>(
const_cast<char*>(pcc)
);

or:

int *p = (char*)pcc;

Very much the former. The horrible code emphasises the horrible action!
And,
size_t i = static_cast<size_t>(-1);

or:

size_t i = (size_t)-1;
The former.

--
Ian Collins.
Jul 11 '06 #11

P: n/a

"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:fO*******************@news.indigo.ie...
dio posted:
>Frederick Gotham <fg*******@SPAM.comwrote:
>>The major drawback of the new-style casts is that they take up far too
much horizontal screen space.

Yes, which should serve as a visual reminder that a design that relies
heavily on casts is perhaps not ideal.


I'm out of nappies now though, and I can judge sensibly as to when I
should
use what kind of cast. Would you prefer:

int *p = reinterpret_cast<int*>(
const_cast<char*>(pcc)
);
This one. It spells out exactly what is going on.
>
or:

int *p = (char*)pcc;
And,
size_t i = static_cast<size_t>(-1);
This one.
or:

size_t i = (size_t)-1;
(Second example is intended to supress a compiler warning)
--

Frederick Gotham

Jul 12 '06 #12

P: n/a
Frederick Gotham wrote:
Victor Bazarov posted:
>Frederick Gotham wrote:
>>I have a simple rule-of-thumb:

If you can use static_cast, then use static_cast.

If you can't use static_cast, then use reinterpret_cast.

I have a simple preceding rule:

If you can do it without a cast, do not use any cast.

Naturally ; )
I tend to use the old-style casts now and again too, e.g.:

enum { len = 64U };

int array[len];

for(size_t i = len - 1; (size_t)-1 != i; --i)
I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)

But I think that's just because C style casts look so old-style to me
now ;-)
Or if I need a reinterpret_cast and a const_cast at the same time:

char const *pc = 0;

int *pi = (int*)pc;

/* A very contrived example, I realise! */
That's an example of a situation where I would definitely go with the C++
style casts. One important advantage is that someone reading the code will
immediately see that I really intended to cast away the constness and
didn't just get it in by accident.

Jul 13 '06 #13

P: n/a
Rolf Magnus wrote:
>
I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)

But I think that's just because C style casts look so old-style to me
now ;-)
But a single arg function-style cast is identical in meaning to the
C-style cast. You're back to it possibly meaning static, const,
reinterpret or combinations of the above (as well as busting access
control which there is no C++-style equivelent to).
Jul 13 '06 #14

P: n/a
Ron Natalie wrote:
Rolf Magnus wrote:
>>
I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)

But I think that's just because C style casts look so old-style to me
now ;-)

But a single arg function-style cast is identical in meaning to the
C-style cast. You're back to it possibly meaning static, const,
reinterpret or combinations of the above (as well as busting access
control which there is no C++-style equivelent to).
I know. As I wrote, it's just that the C style cast looks more C'is than the
constructor style. Also note that none of the things you mentioned are an
issue in the above code example.

Jul 13 '06 #15

P: n/a
"Ron Natalie" <ro*@spamcop.netwrote in message
news:44***********************@news.newshosting.co m...
Rolf Magnus wrote:
>>
I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)

But I think that's just because C style casts look so old-style to me
now ;-)

But a single arg function-style cast is identical in meaning to the
C-style cast. You're back to it possibly meaning static, const,
reinterpret or combinations of the above (as well as busting access
control which there is no C++-style equivelent to).
Actually, not at all. size_t(-1) tells me exactly what is going on. This
is a size_t variable that is being initialized to -1. There is no ambiguity
at all. It is not techinically a cast, I don't think.
Jul 13 '06 #16

P: n/a
Jim Langston wrote:
"Ron Natalie" <ro*@spamcop.netwrote in message
news:44***********************@news.newshosting.co m...
>Rolf Magnus wrote:
>>>
I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)

But I think that's just because C style casts look so old-style to me
now ;-)

But a single arg function-style cast is identical in meaning to the
C-style cast. You're back to it possibly meaning static, const,
reinterpret or combinations of the above (as well as busting access
control which there is no C++-style equivelent to).

Actually, not at all. size_t(-1) tells me exactly what is going on. This
is a size_t variable that is being initialized to -1. There is no
ambiguity at all. It is not techinically a cast, I don't think.
size_t is unsigned and can't have negative values. size_t(-1) tells the
compiler that you want -1 converted to size_t, IOW, it's a cast.

Jul 13 '06 #17

P: n/a
In message <e9*************@news.t-online.com>, Rolf Magnus
<ra******@t-online.dewrites
>
I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)
I'd lose the -1 altogether ;-)

for (size_t i = len; i-- != 0; )
--
Richard Herring
Jul 13 '06 #18

P: n/a
Richard Herring posted:
> for(size_t i = len - 1; size_t(-1) != i; --i)

I'd lose the -1 altogether ;-)

for (size_t i = len; i-- != 0; )

Yes but this has re-arranged the natural order of the loop.

I like my "for" loops to have four phases:

(1) The "initialisation stuff" is executed first of all.

(2) The condition is tested.

(3) The body is executed.

(4) The "prepare for next iteration" stuff is executed.
Your example mixes (2) and (4), which I don't like.

--

Frederick Gotham
Jul 13 '06 #19

P: n/a
Rolf Magnus posted:

size_t is unsigned and can't have negative values. size_t(-1) tells the
compiler that you want -1 converted to size_t, IOW, it's a cast.

There's an implicit conversion from int to size_t, so no cast is required.

When dealing with intrinsic types, the following are exactly equivalent:

short(5)

(short)5

I myself prefer the latter, for two reasons:

(1) You can have types which consist of more than one word, e.g.
"unsigned short".
(2) It resembles a cast.

I dislike the former because:

(1) It looks like the construction of a user-defined class type.
(2) It doesn't resemble a cast at all.
(3) You can't use types which consist of more than one word.
--

Frederick Gotham
Jul 13 '06 #20

P: n/a
Frederick Gotham wrote:
Rolf Magnus posted:

>size_t is unsigned and can't have negative values. size_t(-1) tells the
compiler that you want -1 converted to size_t, IOW, it's a cast.


There's an implicit conversion from int to size_t, so no cast is required.
Well, it's there, no matter if it's required or not.
When dealing with intrinsic types, the following are exactly equivalent:

short(5)

(short)5
Yes. Both are casts.
I myself prefer the latter, for two reasons:

(1) You can have types which consist of more than one word, e.g.
"unsigned short".
That's a good point.
(2) It resembles a cast.
Well, it is a cast, just like the first one.
I dislike the former because:

(1) It looks like the construction of a user-defined class type.
That's one reason why I like it. It uses built-in types more consistently
with classes by using the same syntax.
Btw: What do you do in a template, where the type might be either one?
(2) It doesn't resemble a cast at all.
Well, if you are used to the latter, because you know it from C, then you
might think like that. But basically, none of the two looks more "castish"
than the other.
(3) You can't use types which consist of more than one word.
Yes, that's a restriction that will hopefully be fixed some time.
One thing I like about it is that the value is in parenthesis, so in a
longer exression, it's easier to see which part of it is cast.
Jul 13 '06 #21

P: n/a
In message <xQ*******************@news.indigo.ie>, Frederick Gotham
<fg*******@SPAM.comwrites
>Richard Herring posted:
>> for(size_t i = len - 1; size_t(-1) != i; --i)

I'd lose the -1 altogether ;-)

for (size_t i = len; i-- != 0; )


Yes but this has re-arranged the natural order of the loop.

I like my "for" loops to have four phases:

(1) The "initialisation stuff" is executed first of all.

(2) The condition is tested.

(3) The body is executed.

(4) The "prepare for next iteration" stuff is executed.
Your example mixes (2) and (4), which I don't like.
It puts (4) before (3), that's all. It's just another idiom, and a very
clear one once you're used to it. The only numbers that appear in it are
0 and len, exactly the same as for the forward loop. Other solutions all
require an off-by-one representation of the index and either mix signed
and unsigned, as with the cast above, or do something even more
contorted.

--
Richard Herring
Jul 13 '06 #22

P: n/a
Richard Herring posted:

>>Your example mixes (2) and (4), which I don't like.
It puts (4) before (3), that's all. It's just another idiom, and a very
clear one once you're used to it. The only numbers that appear in it are
0 and len, exactly the same as for the forward loop. Other solutions all
require an off-by-one representation of the index and either mix signed
and unsigned, as with the cast above, or do something even more
contorted.

Let's put it down to a difference in taste : ).
--

Frederick Gotham
Jul 13 '06 #23

P: n/a
Jim Langston wrote:
"Ron Natalie" <ro*@spamcop.netwrote in message
news:44***********************@news.newshosting.co m...
>Rolf Magnus wrote:
>>I tend to use constructor-style casts in such a situation:

for(size_t i = len - 1; size_t(-1) != i; --i)

But I think that's just because C style casts look so old-style to me
now ;-)
But a single arg function-style cast is identical in meaning to the
C-style cast. You're back to it possibly meaning static, const,
reinterpret or combinations of the above (as well as busting access
control which there is no C++-style equivelent to).

Actually, not at all. size_t(-1) tells me exactly what is going on. This
is a size_t variable that is being initialized to -1. There is no ambiguity
at all. It is not techinically a cast, I don't think.

It's is exactly the same as the c-style cast.
The definition of the "explicit type conversion (functional notation)"
says:

If the expression list is a single expression, the type conversion
expression is equivalent (in definedness, and if defined in meaning) to
the corresponding cast expression (5.4).
Jul 13 '06 #24

P: n/a
Frederick Gotham wrote:
When dealing with intrinsic types, the following are exactly equivalent:

short(5)

(short)5
They are exactly equivelent no matter WHAT type is being used.
>
Jul 13 '06 #25

This discussion thread is closed

Replies have been disabled for this discussion.