Connecting Tech Pros Worldwide Help | Site Map

reinterpret_cast<>

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 22nd, 2005, 06:48 AM
Aman
Guest
 
Posts: n/a
Default reinterpret_cast<>

Hi,
wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3

trying to see the byte order of an int or short int by converting to
char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
why would that be ?


int main()
{
int x=0x01020304 ;
int* ipt = &x ;
cout << "ipt : "<< hex << ipt << endl ; // ok ---
char* cpt = reinterpret_cast<char*>(ipt) ;
cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!!
short int* spt = reinterpret_cast<short int*> (ipt) ;
cout << "spt : " << hex << spt <<endl ; // ok ---

}

regards,
Aman.


--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG

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

  #2  
Old July 22nd, 2005, 06:48 AM
Mike Wahler
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>


"Aman" <aman@techie.com> wrote in message
news:4069be0f43c5d3619e70e2c68cc331c1.26421@mygate .mailgate.org...[color=blue]
> Hi,
> wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3
>
> trying to see the byte order of an int or short int by converting to
> char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
> why would that be ?[/color]

It is.
[color=blue]
>
>
> int main()
> {
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color]

The stream inserter (<<) for type 'char*' interprets the argument
as a pointer to a 'C-style' string (zero terminated array of char).
e.g.
char *p = "hello";
cout << p << '\n'; /* prints "hello" */

On of two things is happening:

- sizeof(int) on your system is four bytes, in which case none
of them has a value of zero, producing 'undefined behavior', since
cout<< will run off the end of your array.

-sizeof(int) is more than four bytes, in which case some of them
have zero value, and it appears that on your machine, a zero
is stored before any of the nonzero bytes, in which case
cout << cpt terminates before any output.

Try:

for(size_t i = 0; i < sizeof x; ++i)
cout << hex << cpt[i];
cout << '\n';


-Mike


  #3  
Old July 22nd, 2005, 06:48 AM
Mike Wahler
Guest
 
Posts: n/a
Default Re: (corr) reinterpret_cast<>

"Mike Wahler" <mkwahler@mkwahler.net> wrote in message
news:x4t_b.6318$aT1.4289@newsread1.news.pas.earthl ink.net...[color=blue]
>
> Try:
>
> for(size_t i = 0; i < sizeof x; ++i)
> cout << hex << cpt[i];[/color]

We need to cast to int to get the textual representation of
the byte's value:

cout << hex << static_cast<int>(cpt[i]);

Sorry for the oversight.

-Mike


  #4  
Old July 22nd, 2005, 06:48 AM
Makhno
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

> trying to see the byte order of an int or short int by converting to[color=blue]
> char*[/color]

Why not use a union?


  #5  
Old July 22nd, 2005, 06:48 AM
Rolf Magnus
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

Makhno wrote:
[color=blue][color=green]
>> trying to see the byte order of an int or short int by converting to
>> char*[/color]
>
> Why not use a union?[/color]

Because unions are not made for such things?

  #6  
Old July 22nd, 2005, 06:48 AM
Rob Williscroft
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

Aman wrote in news:4069be0f43c5d3619e70e2c68cc331c1.26421
@mygate.mailgate.org:
[color=blue]
> Hi,
> wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3
>
> trying to see the byte order of an int or short int by converting to
> char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
> why would that be ?
>
>
> int main()
> {
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---[/color]

The above should output the same as if you wrote:

cout << &x << endl;

i.e. the address of x, however that is printed.
[color=blue]
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color]

cout << "cpt : " << hex << unsigned(*cpt) << endl;
[color=blue]
> short int* spt = reinterpret_cast<short int*> (ipt) ;
> cout << "spt : " << hex << spt <<endl ; // ok ---[/color]

As for ipt above.
[color=blue]
>
> }
>[/color]
#include <iostream>
#include <ostream>

int main()
{
using namespace std;
char *cpt = "test-string";
cout << cpt << endl;
}

should output test-string. i.e. the streams output a "string" for
char *'s and a memory address for other pointers.

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
  #7  
Old July 22nd, 2005, 06:49 AM
kanze@gabi-soft.fr
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

"Mike Wahler" <mkwahler@mkwahler.net> wrote in message
news:<x4t_b.6318$aT1.4289@newsread1.news.pas.earth link.net>...[color=blue]
> "Aman" <aman@techie.com> wrote in message
> news:4069be0f43c5d3619e70e2c68cc331c1.26421@mygate .mailgate.org...[color=green]
> > wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3[/color][/color]
[color=blue][color=green]
> > trying to see the byte order of an int or short int by converting to
> > char*. doesn't work. the char* cpt doesn't seem to be initialized
> > !!. why would that be?[/color][/color]
[color=blue]
> It is.[/color]
[color=blue][color=green]
> > int main()
> > {
> > int x=0x01020304 ;
> > int* ipt = &x ;
> > cout << "ipt : "<< hex << ipt << endl ; // ok ---
> > char* cpt = reinterpret_cast<char*>(ipt) ;
> > cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color][/color]
[color=blue]
> The stream inserter (<<) for type 'char*' interprets the argument as a
> pointer to a 'C-style' string (zero terminated array of char).
> e.g.
> char *p = "hello";
> cout << p << '\n'; /* prints "hello" */[/color]
[color=blue]
> One of two things is happening:[/color]
[color=blue]
> - sizeof(int) on your system is four bytes, in which case none
> of them has a value of zero, producing 'undefined behavior', since
> cout<< will run off the end of your array.[/color]

This is his case. Doubtlessly, x is followed fairly soon by a byte
containing 0, because he doesn't get a crash, nor see any output.
(Also, the characters '\001', '\002', '\003'and '\004' don't cause any
visual display.)
[color=blue]
> -sizeof(int) is more than four bytes, in which case some of them
> have zero value, and it appears that on your machine, a zero
> is stored before any of the nonzero bytes, in which case
> cout << cpt terminates before any output.[/color]
[color=blue]
> Try:[/color]
[color=blue]
> for(size_t i = 0; i < sizeof x; ++i)
> cout << hex << cpt[i];
> cout << '\n';[/color]

No better: cpt[i] has type char, so he outputs the byte as a textual
char. Try:

cout << hex << static_cast< int >( cpt[ i ] ) ;

in the loop.

(And of course, the usual disclaimers concerning byte order apply: it
doesn't mean anything, there are more than two possibilities, and if you
need to know, you are doing something grieviously wrong in your code.)

--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
  #8  
Old July 22nd, 2005, 06:49 AM
kanze@gabi-soft.fr
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

Rolf Magnus <ramagnus@t-online.de> wrote in message
news:<c1e5c1$skm$00$2@news.t-online.com>...[color=blue]
> Makhno wrote:[/color]
[color=blue][color=green][color=darkred]
> >> trying to see the byte order of an int or short int by converting
> >> to char*[/color][/color][/color]
[color=blue][color=green]
> > Why not use a union?[/color][/color]
[color=blue]
> Because unions are not made for such things?[/color]

And what he is doing is?

Technically, you're right, in that a union would involve undefined
behavior, where you are allowed to cast an arbitrary pointer to char* or
to unsigned char* and access the memory as an array of bytes. But a
union will work equally well in practice.

And of course, given his code, "equally well" means not at all. Which
was the purpose of his posting. Whether you use a union, or a char*
which you dereference, you must cast to int to avoid treating the char
as a character.

--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
  #9  
Old July 22nd, 2005, 06:49 AM
Jeff Schwab
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

Rolf Magnus wrote:[color=blue]
> Makhno wrote:
>
>[color=green][color=darkred]
>>>trying to see the byte order of an int or short int by converting to
>>>char*[/color]
>>
>>Why not use a union?[/color]
>
>
> Because unions are not made for such things?
>[/color]

It's relatively slow and/or difficult to find all uses of a union within
a set of source code, but it's easy to grep for "cast".

  #10  
Old July 22nd, 2005, 06:49 AM
Jack Applin
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

In comp.lang.c++.moderated Aman <aman@techie.com> wrote:
[color=blue]
> trying to see the byte order of an int or short int by converting to
> char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
> why would that be ?
>
> int main()
> {
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color]

A char * is different from an int * in a crucial way: when you send a
char * to an output stream, C++ doesn't print the pointer, C++ prints
the CHARACTERS that the pointer points to!

cout << "Hello there\n";

That was a const char *, but you wouldn't expect hex, would you?

For this non-portable program, cast your char * to another pointer type:

cout << "cpt : " << hex << (void *) cpt <<endl ; // NO output for cpt !!!

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
  #11  
Old July 22nd, 2005, 06:49 AM
Ron Samuel Klatchko
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

"Aman" <aman@techie.com> wrote in message news:<4069be0f43c5d3619e70e2c68cc331c1.26421@mygat e.mailgate.org>...[color=blue]
> int main()
> {
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!!
>
> }[/color]

The iostream code assumes that a char* is a pointer to a string that
is '\0' terminated. So iostreams is dereferencing the pointer and
printing out each character until it finds a '\0'.

Most likely, when that bit pattern is turned into a pointer and
dereferenced, there is a '\0' byte in that place in memory.

You're lucky the code ran and did nothing instead of crashing when it
tried to dereference a random piece of memory.

samuel

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
  #12  
Old July 22nd, 2005, 06:49 AM
Balog Pal
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

"Aman" <aman@techie.com> wrote in message
news:4069be0f43c5d3619e70e2c68cc331c1.26421@mygate .mailgate.org...[color=blue]
>
> trying to see the byte order of an int or short int by converting to
> char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
> why would that be ?
>
> int main()
> {
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!!
> short int* spt = reinterpret_cast<short int*> (ipt) ;
> cout << "spt : " << hex << spt <<endl ; // ok ---
> }[/color]

Better try output wia printf

You're most likely tricked by the streams, char* is not threated as a
pointer but as a string, and is output as such. Or redirect the output to
a file and hexdump it. Or change your x init to 0x40414243

Paul



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
  #13  
Old July 22nd, 2005, 06:55 AM
Mike Wahler
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>


<kanze@gabi-soft.fr> wrote in message
news:d6652001.0402240250.7a33a51d@posting.google.c om...[color=blue]
> "Mike Wahler" <mkwahler@mkwahler.net> wrote in message
> news:<x4t_b.6318$aT1.4289@newsread1.news.pas.earth link.net>...[color=green]
> > "Aman" <aman@techie.com> wrote in message
> > news:4069be0f43c5d3619e70e2c68cc331c1.26421@mygate .mailgate.org...[color=darkred]
> > > wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3[/color][/color]
>[color=green][color=darkred]
> > > trying to see the byte order of an int or short int by converting to
> > > char*. doesn't work. the char* cpt doesn't seem to be initialized
> > > !!. why would that be?[/color][/color]
>[color=green]
> > It is.[/color]
>[color=green][color=darkred]
> > > int main()
> > > {
> > > int x=0x01020304 ;
> > > int* ipt = &x ;
> > > cout << "ipt : "<< hex << ipt << endl ; // ok ---
> > > char* cpt = reinterpret_cast<char*>(ipt) ;
> > > cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color][/color]
>[color=green]
> > The stream inserter (<<) for type 'char*' interprets the argument as a
> > pointer to a 'C-style' string (zero terminated array of char).
> > e.g.
> > char *p = "hello";
> > cout << p << '\n'; /* prints "hello" */[/color]
>[color=green]
> > One of two things is happening:[/color]
>[color=green]
> > - sizeof(int) on your system is four bytes, in which case none
> > of them has a value of zero, producing 'undefined behavior', since
> > cout<< will run off the end of your array.[/color]
>
> This is his case.[/color]


How do you know?
[color=blue]
> Doubtlessly, x is followed fairly soon by a byte
> containing 0, because he doesn't get a crash, nor see any output.
> (Also, the characters '\001', '\002', '\003'and '\004' don't cause any
> visual display.)[/color]

How do you know? Remember we cannot assume a particular character set.
[color=blue]
>[color=green]
> > -sizeof(int) is more than four bytes, in which case some of them
> > have zero value, and it appears that on your machine, a zero
> > is stored before any of the nonzero bytes, in which case
> > cout << cpt terminates before any output.[/color]
>[color=green]
> > Try:[/color]
>[color=green]
> > for(size_t i = 0; i < sizeof x; ++i)
> > cout << hex << cpt[i];
> > cout << '\n';[/color]
>
> No better: cpt[i] has type char, so he outputs the byte as a textual
> char. Try:
>
> cout << hex << static_cast< int >( cpt[ i ] ) ;
>
> in the loop.[/color]

Yes, I posted a correction almost immediately with this same code.

-Mike


  #14  
Old July 22nd, 2005, 06:55 AM
Aman Angrish
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>


[color=blue]
> Technically, you're right, in that a union would involve undefined
> behavior, where you are allowed to cast an arbitrary pointer to char* or
> to unsigned char* and access the memory as an array of bytes. But a
> union will work equally well in practice.[/color]

that is correct . I initially tried with the union too , but got
no output because of the same reason (char* interpretation by cout) .

thanks !!
Aman.

[color=blue]
> And of course, given his code, "equally well" means not at all. Which
> was the purpose of his posting. Whether you use a union, or a char*
> which you dereference, you must cast to int to avoid treating the char
> as a character.
>[/color]


--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
  #15  
Old July 22nd, 2005, 06:56 AM
Francis Glassborow
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

In message <4069be0f43c5d3619e70e2c68cc331c1.26421@mygate.mai lgate.org>,
Aman <aman@techie.com> writes[color=blue]
>Hi,
>wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3
>
>trying to see the byte order of an int or short int by converting to
>char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
>why would that be ?
>
>
>int main()
>{
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color]

When you use 'operator <<' applied to an ostream and a char * the result
is an attempt to output a null terminated C-style string. There is no
reason to expect the bytes constituting the binary code for x to be such
a string. Indeed there are excellent reasons to suppose that it isn't.
You might also note that none of the bytes encoding x represent
printable characters in either of the common character encodings (ASCII,
EBCDIC).


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
  #16  
Old July 22nd, 2005, 06:56 AM
Ben Hutchings
Guest
 
Posts: n/a
Default Re: reinterpret_cast<>

Aman wrote:[color=blue]
> Hi,
> wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3
>
> trying to see the byte order of an int or short int by converting to
> char* . doesn't work . the char* cpt doesn't seem to be initialized !!.
> why would that be ?[/color]

There is nothing wrong with the initialisation of cpt.
[color=blue]
> int main()
> {
> int x=0x01020304 ;
> int* ipt = &x ;
> cout << "ipt : "<< hex << ipt << endl ; // ok ---
> char* cpt = reinterpret_cast<char*>(ipt) ;
> cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color]

If you write a char-pointer to an ostream, it is treated as a pointer
to a null-terminated string. But cpt doesn't point to a
null-terminated string; it points to the bytes {1, 2, 3, 4} or {4, 3,
2, 1} (depending on which architecture you are running SunOS on).
which don't correspond to printable characters. Note that since these
don't include a null byte the formatting function continues to search
for a null byte in the memory after x. This has undefined behaviour,
so don't tell it to do this!

So you need to convert cpt to void * before printing it:

cout << "cpt : " << hex << static_cast<void *>(cpt) << endl;
[color=blue]
> short int* spt = reinterpret_cast<short int*> (ipt) ;
> cout << "spt : " << hex << spt <<endl ; // ok ---[/color]

I'm not convinced that this is generally safe, because the result of
the reinterpret_cast is unspecified and so might not be convertible to
void *.
[color=blue]
>
> }[/color]

I wonder whether this program will do what you intend, even with the
output corrected. There is no guarantee that you can use *(short *)&x
to access the least significant 16 bits (or however many there are in
a short) of x, so you cannot use the value of (short *)&x to determine
where the least significant 16 bits are stored. The result of the
cast is likely to be the same address as &x, regardless of whether
the machine is big- or little-endian.

The safe way to determine byte order is to look at documentation.
Failing that, print out the bytes cpt[0] to cpt[sizeof(x)-1], but
first convert them to unsigned int so that they are treated as numbers
and not character codes.

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

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,662 network members.