Connecting Tech Pros Worldwide Help | Site Map

reinterpret_cast<>

Aman
Guest
 
Posts: n/a
#1: Jul 22 '05
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! ]
Mike Wahler
Guest
 
Posts: n/a
#2: Jul 22 '05

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


Mike Wahler
Guest
 
Posts: n/a
#3: Jul 22 '05

re: 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


Makhno
Guest
 
Posts: n/a
#4: Jul 22 '05

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?


Rolf Magnus
Guest
 
Posts: n/a
#5: Jul 22 '05

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?

Rob Williscroft
Guest
 
Posts: n/a
#6: Jul 22 '05

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! ]
kanze@gabi-soft.fr
Guest
 
Posts: n/a
#7: Jul 22 '05

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
kanze@gabi-soft.fr
Guest
 
Posts: n/a
#8: Jul 22 '05

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
Jeff Schwab
Guest
 
Posts: n/a
#9: Jul 22 '05

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".

Jack Applin
Guest
 
Posts: n/a
#10: Jul 22 '05

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! ]
Ron Samuel Klatchko
Guest
 
Posts: n/a
#11: Jul 22 '05

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! ]
Balog Pal
Guest
 
Posts: n/a
#12: Jul 22 '05

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! ]
Mike Wahler
Guest
 
Posts: n/a
#13: Jul 22 '05

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


Aman Angrish
Guest
 
Posts: n/a
#14: Jul 22 '05

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! ]
Francis Glassborow
Guest
 
Posts: n/a
#15: Jul 22 '05

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! ]
Ben Hutchings
Guest
 
Posts: n/a
#16: Jul 22 '05

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! ]
Closed Thread