C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

static_cast vs. reinterpret_cast
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Frank A. Uepping
Guest





PostPosted: Tue Aug 12, 2003 11:01 pm    Post subject: static_cast vs. reinterpret_cast Reply with quote



Hello,
assume we have this definition:

void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.
That is, f() could be invoked with a `char*', `unsigend char*' or 'int*'.
(Of course, this question has a somewhat theoretical nature, however.)

Is the static_cast<> the right candidate for this job or reinterpret_cast<>?

/FAU


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Erik Max Francis
Guest





PostPosted: Wed Aug 13, 2003 7:39 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote



"Frank A. Uepping" wrote:

Quote:
Is the static_cast<> the right candidate for this job or
reinterpret_cast<>?

static_cast is the right operator. Remember that static_cast invokes a
well-defined conversion, and a conversion from T * to void * or back
(for some data type T) is always well-defined.

--
Erik Max Francis && [email]max (AT) alcyone (DOT) com[/email] && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ I needed sunshine in my day / Something to wash away the pain
__/ Zhane

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Wed Aug 13, 2003 7:52 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote



"Frank A. Uepping" <Frank.Uepping (AT) t-online (DOT) de> wrote


Quote:
void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.
That is, f() could be invoked with a `char*', `unsigend char*' or 'int*'.
(Of course, this question has a somewhat theoretical nature, however.)

Is the static_cast<> the right candidate for this job or
reinterpret_cast<>?


Good question. Going from T* to char* requires a reinterpret_cast, which is
implementation defined, dangerous, etc. Going from T* to void* requires
nothing, then to go to char* to anything* can use static_cast.

Section 3.9.2 item 4 says:

Objects of cv-qualified or cv-unqualified type void* can be used to point to
objects of unknown type. A void* shall be able to hold any object pointer.
A cv-qualified or cv-unqualified void* shall have the same representation
and alignment requirements as a cv-qualified or cv-unqualified char*.

But it's still confusing.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jack Klein
Guest





PostPosted: Wed Aug 13, 2003 7:56 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

On 12 Aug 2003 19:01:13 -0400, "Frank A. Uepping"
<Frank.Uepping (AT) t-online (DOT) de> wrote in comp.lang.c++.moderated:

Quote:
Hello,
assume we have this definition:

void f(void* p)
{
...
// E.g.: Need to mangle *p

You are mistaken. The memcpy() function takes two pointer arguments
of type void*.

Quote:
memcpy(static_cast<char*>(p) + i, ...);

Oh, you need to cast the pointer to character type to do pointer
arithmetic.

Quote:
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.
That is, f() could be invoked with a `char*', `unsigend char*' or 'int*'.
(Of course, this question has a somewhat theoretical nature, however.)

Is the static_cast<> the right candidate for this job or reinterpret_cast<>?

/FAU

static_cast is the proper operator here. There is absolutely no
change in representation between pointer to void and pointer to char.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Wed Aug 13, 2003 4:07 pm    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

On 12 Aug 2003 19:01:13 -0400, "Frank A. Uepping"
<Frank.Uepping (AT) t-online (DOT) de> wrote:

Quote:
assume we have this definition:

void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.
That is, f() could be invoked with a `char*', `unsigend char*' or 'int*'.
(Of course, this question has a somewhat theoretical nature, however.)

Is the static_cast<> the right candidate for this job or reinterpret_cast<>?

The best hint I can find in the standard is 5.2.9/10 which states that
going from T* to void* to T* using static_cast will work. It says
nothing about anything else like U* to void* to T*. OTOH, 5.2.10/7
states that going from T* to void* to T* using reinterpret_cast will
work and that going from U* to T* is unspecified.

Since nothing is guarantied with either and both are assumed to work in
any reasonable implementation, the question becomes a matter of what
message you wish to send with the code.

int* intPun (void* p) { return static_cast<int*>(p); }

cout << hex;
float f(1f);
cout << *reinterpret_cast cout << *static_cast cout << *intPun(&f);
int i;
memcpy(&i, &f, sizeof(i));
cout << i;

The first is an honest statement that nasty things are taking place.
The next three are attempts to hide the nasty things from view. In
your case of using memcpy to overwrite bytes at some offset into an
object, I suspect nasty things and would send the reinterpret message
to other programmers.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bo Persson
Guest





PostPosted: Wed Aug 13, 2003 10:50 pm    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote


"Frank A. Uepping" <Frank.Uepping (AT) t-online (DOT) de> skrev i meddelandet
news:bhbeht$oer$00$1 (AT) news (DOT) t-online.com...
Quote:
Hello,
assume we have this definition:

void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);

Here you tell the compiler "p actually points to a char". If that is
so, why not state that in the function header?

Quote:
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.
That is, f() could be invoked with a `char*', `unsigend char*' or
'int*'.
(Of course, this question has a somewhat theoretical nature,
however.)

Is the static_cast<> the right candidate for this job or
reinterpret_cast<>?


It depends on what you are trying to do. If you (for some reason) need
some pointer arithmetic in the function, why don't you just declare it
as

template<class T>
void f(T* p)
{

memcpy(p + i, ... );

}

and the compiler will fix it for any type that supports having i added
to it.

Usually the right question is not "What cast to use", but more often
"Why use a cast in the first place". Old C code often use casts
(especially casts to/from void*), where proper C++ code would use
overloading or inheritance.

Bo Persson
[email]bop2 (AT) telia (DOT) com[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Frank A. Uepping
Guest





PostPosted: Thu Aug 14, 2003 9:00 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

John Potter wrote:

Quote:
On 12 Aug 2003 19:01:13 -0400, "Frank A. Uepping"
[email]Frank.Uepping (AT) t-online (DOT) de[/email]> wrote:

assume we have this definition:

void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.
That is, f() could be invoked with a `char*', `unsigend char*' or 'int*'.
(Of course, this question has a somewhat theoretical nature, however.)

Is the static_cast<> the right candidate for this job or
reinterpret_cast<>?

The best hint I can find in the standard is 5.2.9/10 which states that
going from T* to void* to T* using static_cast will work. It says
nothing about anything else like U* to void* to T*. OTOH, 5.2.10/7
states that going from T* to void* to T* using reinterpret_cast will
work and that going from U* to T* is unspecified.

Since nothing is guarantied with either and both are assumed to work in
any reasonable implementation, the question becomes a matter of what
message you wish to send with the code.

int* intPun (void* p) { return static_cast<int*>(p); }

cout << hex;
float f(1f);
cout << *reinterpret_cast cout << *static_cast cout << *intPun(&f);
int i;
memcpy(&i, &f, sizeof(i));
cout << i;

The first is an honest statement that nasty things are taking place.
The next three are attempts to hide the nasty things from view. In
your case of using memcpy to overwrite bytes at some offset into an
object, I suspect nasty things and would send the reinterpret message
to other programmers.

John

Fundamentally, we have a conversion from T* -> char* over a void*;
and for this kind of conversions (T* -> U*) the reinterpret_cast<> is
the means.

However, perhaps we should change our perspective on what we want to
achieve. The objective of the conversion is to enable us to do (char)
pointer arithmetic. With that in mind and considering 3.9.2-4:

"Objects of cvqualified (3.9.3) or cvunqualified type void* (pointer to
void), can be used to point to objects of unknown type. A void* shall be
able to hold any object pointer. A cvqualified or cvunqualified (3.9.3)
void* shall have the same representation and alignment requirements as
a cvqualified or cvunqualified char*."

If a void* has the same representation and alignment requirements
as a char* then a conversion from void* -> char* can be deemed as
"safe" (with safe I mean the value is preserved); in this case a
static_cast<> is more appropriate.

What do you think?

/FAU


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Roger Orr
Guest





PostPosted: Thu Aug 14, 2003 9:12 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

"Frank A. Uepping" <Frank.Uepping (AT) t-online (DOT) de> wrote

Quote:
Hello,
assume we have this definition:

void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);
...
}

The point to consider here is, that p points to a object not
necessarily a char stream.

If 'p' points to an _object_ then I'd be rather careful about trying to
memcpy to it, unless it is POD type.

void* is dangerous since almost everything fits and type checking is turned
off.
I'd prefer the method signature to be more specific, even if it means an
explicit cast at the call site.

Roger Orr
--
MVP in C++ at www.brainbench.com



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jack Klein
Guest





PostPosted: Thu Aug 14, 2003 9:26 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

On 13 Aug 2003 12:06:37 -0400, "Frank A. Uepping"
<Frank.Uepping (AT) t-online (DOT) de> wrote in comp.lang.c++.moderated:

{Excessive quote snipped -mod}

Quote:
What if we want to cast to int*, for example:
memcpy(static_cast<int*>(p) + i, ...);
Is static_cast<> still appropriate?
Consider Section 3.9.2 item 4.

/FAU

Yes, when you are talking about built-in or POD types, static_cast is
correct. So is a C-style cast, although it is deprecated.

But you need to remember that there may be alignment issues if you
start out with a pointer to type A, and end up with a pointer to type
B, and type B has stricter alignment issues than type A. This is
regardless of the type of cast or whether or not you take a detour
through pointer to void.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Fri Aug 15, 2003 2:11 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

On 14 Aug 2003 05:00:42 -0400, "Frank A. Uepping"
<Frank.Uepping (AT) t-online (DOT) de> wrote:

Quote:
If a void* has the same representation and alignment requirements
as a char* then a conversion from void* -> char* can be deemed as
"safe" (with safe I mean the value is preserved); in this case a
static_cast<> is more appropriate.

What do you think?

All casts bypass the type system. In the case of void* to char*,
both static_cast and reinterpret_cast should preserve the value.
Using static_cast<char*>(void*) when the void* was obtained from
other than a char* is sending a false message. In any reasonable
implementation, static_cast<char*>(static_cast<void*>(T*)) should
produce the same result as reinterpret_cast<char*>(T*) which
should not change the effective value.

I don't see anything other than ethics which differs. A
static_cast from void* in a container of T* implemented in terms
of a container of void* is a statement of knowledge that the void*
came from a T*. A reinterpret_cast from void* states that there
is something which has been shown to work that the compiler would
not allow. My logic is that if inlining would require adding a
static_cast to void*, then reinterpret_cast is appropriate. The
double static_cast to replace a reinterpret_cast is legal but
should be rejected as unethical.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Fri Aug 15, 2003 9:34 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

"Bo Persson" <bop2 (AT) telia (DOT) com> wrote


Quote:
void f(void* p)
{
...
// E.g.: Need to mangle *p
memcpy(static_cast<char*>(p) + i, ...);

Here you tell the compiler "p actually points to a char". If that is
so, why not state that in the function header?

We don't want the caller to write stuff like

f(static_cast<char*>(&number));

with static_cast in the function call. We want just f(&number).



Quote:
It depends on what you are trying to do. If you (for some reason) need
some pointer arithmetic in the function, why don't you just declare it
as

template<class T
void f(T* p)
{

memcpy(p + i, ... );

}

and the compiler will fix it for any type that supports having i added
to it.

Usually the right question is not "What cast to use", but more often
"Why use a cast in the first place". Old C code often use casts
(especially casts to/from void*), where proper C++ code would use
overloading or inheritance.

For my binary_ostream class I use reinterpret_cast to get the char*
representation. The template function is hidden because we don't want the
user to call binary_ostream::operator<<(const NonPOD&). Is there a better
way?


class binary_ostream : public std::ios
{
public:
binary_ostream(std::streambuf * streambuf) : std::ios(streambuf) { }

binary_ostream& operator<<(const signed short &x) { return put(x); }
binary_ostream& operator<<(const unsigned short &x) { return put(x); }
binary_ostream& operator<<(const signed int &x) { return put(x); }
binary_ostream& operator<<(const unsigned int &x) { return put(x); }
... for all fundamental types ...

private:
template };


template <class T>
inline enhanced::binary_ostream& enhanced::binary_ostream::put(const T& x)
{
if (good() || eof())
{
const char * bits=reinterpret_cast<const char*>(&x);
const int num=sizeof(T);
std::streamsize write=rdbuf()->sputn(bits,num);
if (write!=num) clear(failbit);
}
return *this;
}


--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Fri Aug 15, 2003 5:38 pm    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

In article <nhsnjvg8lo5l35pnev8bp7l3o51ch16q3e (AT) 4ax (DOT) com>, Doug Harrison
<dsh (AT) mvps (DOT) org> writes
Quote:
John Potter wrote:

OTOH, 5.2.10/7
states that going from T* to void* to T* using reinterpret_cast will
work

Actually, it talks about pointers to object types, and void is not an
object type. AFAICT, the standard prohibits reinterpret_cast to and
from void*.

I think this is a defect Anyone like to justify the exclusion of
conversions between void* and T* with reinterpret_cast?



--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Sat Aug 16, 2003 8:10 am    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

"Francis Glassborow" <francis (AT) robinton (DOT) demon.co.uk> wrote in message
Quote:
I think this is a defect Anyone like to justify the exclusion of
conversions between void* and T* with reinterpret_cast?

That's what static_cast is for Smile.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Sat Aug 16, 2003 1:28 pm    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

In article <xNc%a.75554$_R5.29002660 (AT) news4 (DOT) srv.hcvlny.cv.net>, Andriy
Gapon <agaponrmthis (AT) optonline (DOT) net> writes
Quote:
Francis Glassborow wrote:
I think this is a defect Anyone like to justify the exclusion of
conversions between void* and T* with reinterpret_cast?

re-interpreting to void* doesn't make sense because void can not be interpreted ?

Language design isn't Linguistic Philosophy 101. The problem manifests
in templates because it means that I cannot write a conversion from U*
to V* where U and V are template type parameters. Of course you may
think that the programmer should not do that but is it the task of the
language to get in the way?


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Sat Aug 16, 2003 1:30 pm    Post subject: Re: static_cast vs. reinterpret_cast Reply with quote

In article
<Oij%a.102340$0v4.7078105 (AT) bgtnsc04-news (DOT) ops.worldnet.att.net>, Siemel
Naran <SiemelNaran (AT) REMOVE (DOT) att.net> writes
Quote:
"Francis Glassborow" <francis (AT) robinton (DOT) demon.co.uk> wrote in message
I think this is a defect Anyone like to justify the exclusion of
conversions between void* and T* with reinterpret_cast?

That's what static_cast is for Smile.

Unfortunately that does not work for generic programming.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.