reinterpret_cast<>

Discussion in 'C++' started by Aman, Feb 23, 2004.

  1. Aman

    Aman Guest

    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! ]
     
    Aman, Feb 23, 2004
    #1
    1. Advertising

  2. Aman

    Mike Wahler Guest

    "Aman" <> wrote in message
    news:...
    > 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;
    cout << '\n';


    -Mike
     
    Mike Wahler, Feb 23, 2004
    #2
    1. Advertising

  3. Aman

    Mike Wahler Guest

    Re: (corr) reinterpret_cast<>

    "Mike Wahler" <> wrote in message
    news:x4t_b.6318$...
    >
    > Try:
    >
    > for(size_t i = 0; i < sizeof x; ++i)
    > cout << hex << cpt;


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

    cout << hex << static_cast<int>(cpt);

    Sorry for the oversight.

    -Mike
     
    Mike Wahler, Feb 23, 2004
    #3
  4. Aman

    Makhno Guest

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


    Why not use a union?
     
    Makhno, Feb 23, 2004
    #4
  5. Aman

    Rolf Magnus Guest

    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?
     
    Rolf Magnus, Feb 24, 2004
    #5
  6. 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! ]
     
    Rob Williscroft, Feb 24, 2004
    #6
  7. Aman

    Guest

    "Mike Wahler" <> wrote in message
    news:<x4t_b.6318$>...
    > "Aman" <> wrote in message
    > news:...
    > > 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;
    > cout << '\n';


    No better: cpt 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:
    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
     
    , Feb 24, 2004
    #7
  8. Aman

    Guest

    Rolf Magnus <> wrote in message
    news:<c1e5c1$skm$00$-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:
    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
     
    , Feb 24, 2004
    #8
  9. Aman

    Jeff Schwab Guest

    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".
     
    Jeff Schwab, Feb 24, 2004
    #9
  10. Aman

    Jack Applin Guest

    In comp.lang.c++.moderated Aman <> 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! ]
     
    Jack Applin, Feb 24, 2004
    #10
  11. "Aman" <> wrote in message news:<>...
    > 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! ]
     
    Ron Samuel Klatchko, Feb 24, 2004
    #11
  12. Aman

    Balog Pal Guest

    "Aman" <> wrote in message
    news:...
    >
    > 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! ]
     
    Balog Pal, Feb 24, 2004
    #12
  13. Aman

    Mike Wahler Guest

    <> wrote in message
    news:...
    > "Mike Wahler" <> wrote in message
    > news:<x4t_b.6318$>...
    > > "Aman" <> wrote in message
    > > news:...
    > > > 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;
    > > cout << '\n';

    >
    > No better: cpt 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
     
    Mike Wahler, Feb 24, 2004
    #13
  14. Aman

    Aman Angrish Guest


    > 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! ]
     
    Aman Angrish, Feb 24, 2004
    #14
  15. In message <>,
    Aman <> 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! ]
     
    Francis Glassborow, Feb 25, 2004
    #15
  16. 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! ]
     
    Ben Hutchings, Feb 25, 2004
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Suzanne Vogel
    Replies:
    17
    Views:
    812
    Suzanne Vogel
    Jul 7, 2003
  2. Scott Brady Drummonds

    reinterpret_cast<>() v. static_cast<>()

    Scott Brady Drummonds, Jan 13, 2004, in forum: C++
    Replies:
    11
    Views:
    20,703
    Nick Hounsome
    Jan 20, 2004
  3. johny smith

    const_cast, reinterpret_cast

    johny smith, Jun 24, 2004, in forum: C++
    Replies:
    18
    Views:
    3,445
    Old Wolf
    Jun 24, 2004
  4. John Harrison

    reinterpret_cast problem

    John Harrison, Jul 13, 2004, in forum: C++
    Replies:
    6
    Views:
    4,248
    Karthik
    Jul 14, 2004
  5. Alex Vinokur
    Replies:
    1
    Views:
    582
Loading...

Share This Page