reinterpret_cast<>

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Aman

    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_cas t<char*>(ipt) ;
    cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!!
    short int* spt = reinterpret_cas t<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++.m oderated. First time posters: Do this! ]
  • Mike Wahler

    #2
    Re: reinterpret_cas t&lt;&gt;


    "Aman" <aman@techie.co m> wrote in message
    news:4069be0f43 c5d3619e70e2c68 cc331c1.26421@m ygate.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_cas t<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


    Comment

    • Mike Wahler

      #3
      Re: (corr) reinterpret_cas t&lt;&gt;

      "Mike Wahler" <mkwahler@mkwah ler.net> wrote in message
      news:x4t_b.6318 $aT1.4289@newsr ead1.news.pas.e arthlink.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


      Comment

      • Makhno

        #4
        Re: reinterpret_cas t&lt;&gt;

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

        Why not use a union?


        Comment

        • Rolf Magnus

          #5
          Re: reinterpret_cas t&lt;&gt;

          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?

          Comment

          • Rob Williscroft

            #6
            Re: reinterpret_cas t&lt;&gt;

            Aman wrote in news:4069be0f43 c5d3619e70e2c68 cc331c1.26421
            @mygate.mailgat e.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_cas t<char*>(ipt) ;
            > cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!![/color]

            cout << "cpt : " << hex << unsigned(*cpt) << endl;
            [color=blue]
            > short int* spt = reinterpret_cas t<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.
            --


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

            Comment

            • kanze@gabi-soft.fr

              #7
              Re: reinterpret_cas t&lt;&gt;

              "Mike Wahler" <mkwahler@mkwah ler.net> wrote in message
              news:<x4t_b.631 8$aT1.4289@news read1.news.pas. earthlink.net>. ..[color=blue]
              > "Aman" <aman@techie.co m> wrote in message
              > news:4069be0f43 c5d3619e70e2c68 cc331c1.26421@m ygate.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_cas t<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@ga bi-soft.fr
              Conseils en informatique orientée objet/ http://www.gabi-soft.fr
              Beratung in objektorientier ter Datenverarbeitu ng
              11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

              Comment

              • kanze@gabi-soft.fr

                #8
                Re: reinterpret_cas t&lt;&gt;

                Rolf Magnus <ramagnus@t-online.de> wrote in message
                news:<c1e5c1$sk m$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@ga bi-soft.fr
                Conseils en informatique orientée objet/ http://www.gabi-soft.fr
                Beratung in objektorientier ter Datenverarbeitu ng
                11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

                Comment

                • Jeff Schwab

                  #9
                  Re: reinterpret_cas t&lt;&gt;

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

                  Comment

                  • Jack Applin

                    #10
                    Re: reinterpret_cas t&lt;&gt;

                    In comp.lang.c++.m oderated Aman <aman@techie.co m> 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_cas t<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++.m oderated. First time posters: Do this! ]

                    Comment

                    • Ron Samuel Klatchko

                      #11
                      Re: reinterpret_cas t&lt;&gt;

                      "Aman" <aman@techie.co m> wrote in message news:<4069be0f4 3c5d3619e70e2c6 8cc331c1.26421@ mygate.mailgate .org>...[color=blue]
                      > int main()
                      > {
                      > int x=0x01020304 ;
                      > int* ipt = &x ;
                      > cout << "ipt : "<< hex << ipt << endl ; // ok ---
                      > char* cpt = reinterpret_cas t<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++.m oderated. First time posters: Do this! ]

                      Comment

                      • Balog Pal

                        #12
                        Re: reinterpret_cas t&lt;&gt;

                        "Aman" <aman@techie.co m> wrote in message
                        news:4069be0f43 c5d3619e70e2c68 cc331c1.26421@m ygate.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_cas t<char*>(ipt) ;
                        > cout << "cpt : " << hex << cpt <<endl ; // NO output for cpt !!!
                        > short int* spt = reinterpret_cas t<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++.m oderated. First time posters: Do this! ]

                        Comment

                        • Mike Wahler

                          #13
                          Re: reinterpret_cas t&lt;&gt;


                          <kanze@gabi-soft.fr> wrote in message
                          news:d6652001.0 402240250.7a33a 51d@posting.goo gle.com...[color=blue]
                          > "Mike Wahler" <mkwahler@mkwah ler.net> wrote in message
                          > news:<x4t_b.631 8$aT1.4289@news read1.news.pas. earthlink.net>. ..[color=green]
                          > > "Aman" <aman@techie.co m> wrote in message
                          > > news:4069be0f43 c5d3619e70e2c68 cc331c1.26421@m ygate.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_cas t<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


                          Comment

                          • Aman Angrish

                            #14
                            Re: reinterpret_cas t&lt;&gt;


                            [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++.m oderated. First time posters: Do this! ]

                            Comment

                            • Francis Glassborow

                              #15
                              Re: reinterpret_cas t&lt;&gt;

                              In message <4069be0f43c5d3 619e70e2c68cc33 1c1.26421@mygat e.mailgate.org> ,
                              Aman <aman@techie.co m> 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_cas t<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++.m oderated. First time posters: Do this! ]

                              Comment

                              Working...