471,585 Members | 1,165 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,585 software developers and data experts.

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! ]
Jul 22 '05 #1
15 2338

"Aman" <am**@techie.com> wrote in message
news:40************************************@mygate .mailgate.org...
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 ?
It is.


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 !!!


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
Jul 22 '05 #2
"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:x4*****************@newsread1.news.pas.earthl ink.net...

Try:

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


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
Jul 22 '05 #3
> trying to see the byte order of an int or short int by converting to
char*


Why not use a union?
Jul 22 '05 #4
Makhno wrote:
trying to see the byte order of an int or short int by converting to
char*


Why not use a union?


Because unions are not made for such things?

Jul 22 '05 #5
Aman wrote in news:4069be0f43c5d3619e70e2c68cc331c1.26421
@mygate.mailgate.org:
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 ---
The above should output the same as if you wrote:

cout << &x << endl;

i.e. the address of x, however that is printed.
char* cpt = reinterpret_cast<char*>(ipt) ;
cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!!
cout << "cpt : " << hex << unsigned(*cpt) << endl;
short int* spt = reinterpret_cast<short int*> (ipt) ;
cout << "spt : " << hex << spt <<endl ; // ok ---
As for ipt above.

}

#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! ]
Jul 22 '05 #6
"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:<x4*****************@newsread1.news.pas.earth link.net>...
"Aman" <am**@techie.com> wrote in message
news:40************************************@mygate .mailgate.org...
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?
It is. 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 !!!

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" */ One 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.
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.)
-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';


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:ka***@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
Jul 22 '05 #7
Rolf Magnus <ra******@t-online.de> wrote in message
news:<c1*************@news.t-online.com>...
Makhno wrote:
trying to see the byte order of an int or short int by converting
to char*
Why not use a union?

Because unions are not made for such things?


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:ka***@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
Jul 22 '05 #8
Rolf Magnus wrote:
Makhno wrote:

trying to see the byte order of an int or short int by converting to
char*


Why not use a union?

Because unions are not made for such things?


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

Jul 22 '05 #9
In comp.lang.c++.moderated Aman <am**@techie.com> wrote:
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 !!!


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! ]
Jul 22 '05 #10
"Aman" <am**@techie.com> wrote in message news:<40************************************@mygat e.mailgate.org>...
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 !!!

}


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! ]
Jul 22 '05 #11
"Aman" <am**@techie.com> wrote in message
news:40************************************@mygate .mailgate.org...

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 ---
}


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! ]
Jul 22 '05 #12

<ka***@gabi-soft.fr> wrote in message
news:d6**************************@posting.google.c om...
"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:<x4*****************@newsread1.news.pas.earth link.net>...
"Aman" <am**@techie.com> wrote in message
news:40************************************@mygate .mailgate.org...
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?
It is. 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 !!!

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" */

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


This is his case.

How do you know?
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.)
How do you know? Remember we cannot assume a particular character set.
-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';


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.


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

-Mike
Jul 22 '05 #13

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

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.

--
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! ]
Jul 22 '05 #14
In message <40************************************@mygate.mai lgate.org>,
Aman <am**@techie.com> writes
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 !!!


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! ]
Jul 22 '05 #15
Aman wrote:
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 ?
There is nothing wrong with the initialisation of cpt.
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 !!!
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;
short int* spt = reinterpret_cast<short int*> (ipt) ;
cout << "spt : " << hex << spt <<endl ; // ok ---
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 *.

}


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! ]
Jul 22 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Scott Brady Drummonds | last post: by
3 posts views Thread by Nate Barney | last post: by
27 posts views Thread by Noah Roberts | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by
reply views Thread by Anwar ali | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.