how to avoid reinterpret_cast in this snippet?

Discussion in 'C++' started by KK, Dec 1, 2005.

  1. KK

    KK Guest

    Hello all,
    I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    first 12 bytes of it into a string. Below is a code that should work,
    however, how can I avoid reinterpret_cast operator?
    Or Is there a simple way to get around this?
    Thanks.
    -KK
    /* not tested yet */
    typedef unsigned char BYTE
    std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    {
    const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    std::string tmp(chAry,12);
    return chAry;
    }
    KK, Dec 1, 2005
    #1
    1. Advertising

  2. KK

    Ron Natalie Guest

    KK wrote:
    > Hello all,
    > I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    > first 12 bytes of it into a string. Below is a code that should work,
    > however, how can I avoid reinterpret_cast operator?
    > Or Is there a simple way to get around this?
    > Thanks.
    > -KK
    > /* not tested yet */
    > typedef unsigned char BYTE
    > std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    > {
    > const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    > std::string tmp(chAry,12);
    > return chAry;
    > }
    >

    You can't. unsigned char* and char* are not convertible. Even on
    systems where char is inherently unsigned it's a distinct type. The
    cast however should be safe.
    Ron Natalie, Dec 1, 2005
    #2
    1. Advertising

  3. * KK:
    > Hello all,
    > I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    > first 12 bytes of it into a string. Below is a code that should work,
    > however, how can I avoid reinterpret_cast operator?
    > Or Is there a simple way to get around this?
    > Thanks.
    > -KK
    > /* not tested yet */
    > typedef unsigned char BYTE
    > std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    > {
    > const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    > std::string tmp(chAry,12);
    > return chAry;
    > }


    How about

    std::string string12From( const BYTE buffer[], int pos )
    {
    return std::string( buffer+pos, buffer+pos+12 );
    }

    Btw., it's not a good idea to bury magic numbers like 12 in the code.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Dec 1, 2005
    #3
  4. KK

    ben Guest

    KK wrote:
    > Hello all,
    > I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    > first 12 bytes of it into a string. Below is a code that should work,
    > however, how can I avoid reinterpret_cast operator?
    > Or Is there a simple way to get around this?
    > Thanks.
    > -KK
    > /* not tested yet */
    > typedef unsigned char BYTE
    > std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    > {
    > const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    > std::string tmp(chAry,12);
    > return chAry;
    > }
    >



    In addition to Alf's suggestion, here is another choice:

    void GetStringFromByteBuffer(const BYTE* const buffer,
    std::string& s)
    {
    std::copy(buffer, buffer+12, s.begin());
    }

    BYTE buff[19];
    int pos = 6;
    std::string str;

    GetStringFromByteBuffer(
    buff + pos,
    str);

    Ben
    ben, Dec 2, 2005
    #4
  5. * ben:
    > KK wrote:
    > > Hello all,
    > > I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    > > first 12 bytes of it into a string. Below is a code that should work,
    > > however, how can I avoid reinterpret_cast operator?
    > > Or Is there a simple way to get around this?
    > > Thanks.
    > > -KK
    > > /* not tested yet */
    > > typedef unsigned char BYTE
    > > std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    > > {
    > > const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    > > std::string tmp(chAry,12);
    > > return chAry;
    > > }
    > >

    >
    >
    > In addition to Alf's suggestion, here is another choice:
    >
    > void GetStringFromByteBuffer(const BYTE* const buffer,
    > std::string& s)
    > {
    > std::copy(buffer, buffer+12, s.begin());


    Nitpick: that assumes the string s passed as actual argument has size
    12.

    I'd write

    s.assign( buffer, buffer+12 );

    > }
    >
    > BYTE buff[19];
    > int pos = 6;
    > std::string str;


    Oops... ;-)


    > GetStringFromByteBuffer(
    > buff + pos,
    > str);


    I think there's too much apparent magic in the standard library, so it's
    too easy to think a standard algorithm can do no wrong...

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Dec 2, 2005
    #5
  6. On 1 Dec 2005 14:47:10 -0800, "KK" <> wrote:

    >Hello all,
    >I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    >first 12 bytes of it into a string. Below is a code that should work,
    >however, how can I avoid reinterpret_cast operator?
    >Or Is there a simple way to get around this?
    >Thanks.
    >-KK
    >/* not tested yet */
    >typedef unsigned char BYTE
    >std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    >{
    > const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    > std::string tmp(chAry,12);
    > return chAry;
    >}


    Since char and unsigned char are different types, you must use either
    a C-style cast or reinterpret_cast, as you have done. There is really
    no way to avoid it if you must pass unsigned char to this function.

    --
    Bob Hairgrove
    Bob Hairgrove, Dec 2, 2005
    #6
  7. * Bob Hairgrove:
    > On 1 Dec 2005 14:47:10 -0800, "KK" <> wrote:
    >
    > >Hello all,
    > >I have a unsigned char buffer 'buffer[1024]' and I need to convert the
    > >first 12 bytes of it into a string. Below is a code that should work,
    > >however, how can I avoid reinterpret_cast operator?
    > >Or Is there a simple way to get around this?
    > >Thanks.
    > >-KK
    > >/* not tested yet */
    > >typedef unsigned char BYTE
    > >std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
    > >{
    > > const char *chAry = reinterpret_cast <const char *> (buffer + pos);
    > > std::string tmp(chAry,12);
    > > return chAry;
    > >}

    >
    > Since char and unsigned char are different types, you must use either
    > a C-style cast or reinterpret_cast, as you have done. There is really
    > no way to avoid it if you must pass unsigned char to this function.


    You're the second person to state that so I'm interesting in the
    reeasoning.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Dec 2, 2005
    #7
  8. On Fri, 02 Dec 2005 09:58:35 GMT, (Alf P. Steinbach)
    wrote:

    >> Since char and unsigned char are different types, you must use either
    >> a C-style cast or reinterpret_cast, as you have done. There is really
    >> no way to avoid it if you must pass unsigned char to this function.

    >
    >You're the second person to state that so I'm interesting in the
    >reeasoning.


    The reason? Because std::string has no constructor that takes unsigned
    char* as an argument.

    (And I believe that there are more than two others by now... ;)

    --
    Bob Hairgrove
    Bob Hairgrove, Dec 2, 2005
    #8
  9. KK

    Kai-Uwe Bux Guest

    Bob Hairgrove wrote:

    > On Fri, 02 Dec 2005 09:58:35 GMT, (Alf P. Steinbach)
    > wrote:
    >
    >>> Since char and unsigned char are different types, you must use either
    >>> a C-style cast or reinterpret_cast, as you have done. There is really
    >>> no way to avoid it if you must pass unsigned char to this function.

    >>
    >>You're the second person to state that so I'm interesting in the
    >>reeasoning.

    >
    > The reason? Because std::string has no constructor that takes unsigned
    > char* as an argument.


    Hm, std::string has a templated constructor:


    template<class InputIterator>
    basic_string(InputIterator begin, InputIterator end,
    const Allocator& a = Allocator());


    Since unsigned char is convertible to char, this constructor should match.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Dec 2, 2005
    #9
  10. * Bob Hairgrove:
    > On Fri, 02 Dec 2005 09:58:35 GMT, (Alf P. Steinbach)
    > wrote:
    >
    > >> Since char and unsigned char are different types, you must use either
    > >> a C-style cast or reinterpret_cast, as you have done. There is really
    > >> no way to avoid it if you must pass unsigned char to this function.

    > >
    > >You're the second person to state that so I'm interesting in the
    > >reeasoning.

    >
    > The reason? Because std::string has no constructor that takes unsigned
    > char* as an argument.


    That is incorrect.

    > (And I believe that there are more than two others by now... ;)


    That is also incorrect.

    Cheers,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Dec 2, 2005
    #10
  11. On Fri, 02 Dec 2005 05:31:13 -0500, Kai-Uwe Bux <>
    wrote:

    >Hm, std::string has a templated constructor:
    >
    >
    > template<class InputIterator>
    > basic_string(InputIterator begin, InputIterator end,
    > const Allocator& a = Allocator());
    >
    >
    >Since unsigned char is convertible to char, this constructor should match.


    // test_uchar.cpp

    #include <iostream>
    #include <ostream>
    #include <string>

    int main()
    {
    const unsigned char msg[] = "Hello";
    std::string s(msg);
    std::cout << s << std::endl;
    }

    Does that compile on your system?

    --
    Bob Hairgrove
    Bob Hairgrove, Dec 2, 2005
    #11
  12. On Fri, 02 Dec 2005 11:04:26 GMT, (Alf P. Steinbach)
    wrote:

    >> The reason? Because std::string has no constructor that takes unsigned
    >> char* as an argument.

    >
    >That is incorrect.


    // test_uchar.cpp

    #include <iostream>
    #include <ostream>
    #include <string>

    int main()
    {
    const unsigned char msg[] = "Hello";
    std::string s(msg);
    std::cout << msg << std::endl;
    }

    Does that compile on your system?

    --
    Bob Hairgrove
    Bob Hairgrove, Dec 2, 2005
    #12
  13. KK

    Guest

    Bob Hairgrove wrote:
    > On Fri, 02 Dec 2005 11:04:26 GMT, (Alf P. Steinbach)
    > wrote:
    >
    > >> The reason? Because std::string has no constructor that takes unsigned
    > >> char* as an argument.

    > >
    > >That is incorrect.

    >
    > // test_uchar.cpp
    >
    > #include <iostream>
    > #include <ostream>
    > #include <string>
    >
    > int main()
    > {
    > const unsigned char msg[] = "Hello";
    > std::string s(msg);
    > std::cout << msg << std::endl;
    > }
    >
    > Does that compile on your system?


    Nope. However, this does:

    #include <string>
    const unsigned char msg[] = "Hello";
    std::string s(msg,msg+sizeof(msg));

    The statement you're tyring to prove is: "
    std::string has no constructor that takes one argument, of type
    unsigned char*.
    " That statement is of course true, but not really relevant.

    HTH,
    Michiel Salters
    , Dec 2, 2005
    #13
  14. KK

    Neil Cerutti Guest

    On 2005-12-02, Bob Hairgrove <> wrote:
    > On Fri, 02 Dec 2005 11:04:26 GMT, (Alf P. Steinbach)
    > wrote:
    >
    >>> The reason? Because std::string has no constructor that takes unsigned
    >>> char* as an argument.

    >>
    >>That is incorrect.

    >
    > // test_uchar.cpp
    >
    > #include <iostream>
    > #include <ostream>
    > #include <string>
    >
    > int main()
    > {
    > const unsigned char msg[] = "Hello";
    > std::string s(msg);
    > std::cout << msg << std::endl;
    > }
    >
    > Does that compile on your system?
    >
    > --
    > Bob Hairgrove
    >



    --
    Neil Cerutti
    Neil Cerutti, Dec 2, 2005
    #14
  15. KK

    Kai-Uwe Bux Guest

    Bob Hairgrove wrote:

    > On Fri, 02 Dec 2005 05:31:13 -0500, Kai-Uwe Bux <>
    > wrote:
    >
    >>Hm, std::string has a templated constructor:
    >>
    >>
    >> template<class InputIterator>
    >> basic_string(InputIterator begin, InputIterator end,
    >> const Allocator& a = Allocator());
    >>
    >>
    >>Since unsigned char is convertible to char, this constructor should match.

    >
    > // test_uchar.cpp
    >
    > #include <iostream>
    > #include <ostream>
    > #include <string>
    >
    > int main()
    > {
    > const unsigned char msg[] = "Hello";
    > std::string s(msg);
    > std::cout << s << std::endl;
    > }
    >
    > Does that compile on your system?


    Nope, but that is not the constructor I was talking about. The following
    *does* compile:

    // test_uchar.cpp

    #include <iostream>
    #include <ostream>
    #include <string>

    int main()
    {
    const unsigned char msg[] = "Hello";
    std::string s( msg, msg+5 );
    std::cout << s << std::endl;
    }


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Dec 2, 2005
    #15
  16. KK

    Neil Cerutti Guest

    On 2005-12-02, Neil Cerutti <> wrote:
    > On 2005-12-02, Bob Hairgrove <> wrote:
    >> On Fri, 02 Dec 2005 11:04:26 GMT, (Alf P.
    >> Steinbach) wrote:
    >>>> The reason? Because std::string has no constructor that
    >>>> takes unsigned char* as an argument.
    >>>
    >>>That is incorrect.

    >>
    >> // test_uchar.cpp
    >>
    >> #include <iostream>
    >> #include <ostream>
    >> #include <string>
    >>
    >> int main()
    >> {
    >> const unsigned char msg[] = "Hello";
    >> std::string s(msg);
    >> std::cout << msg << std::endl;
    >> }
    >>
    >> Does that compile on your system?


    Oops. Sorry for the all-quote null-response post. The slrn
    configuration setting that allowed this mistake has been sacked.

    I meant to say that it wouldn't compile on my system, but I could
    make it work by using the templated constructor.

    --
    Neil Cerutti
    Neil Cerutti, Dec 2, 2005
    #16
  17. KK

    Ron Natalie Guest

    Kai-Uwe Bux wrote:
    > Bob Hairgrove wrote:
    >
    >> On Fri, 02 Dec 2005 09:58:35 GMT, (Alf P. Steinbach)
    >> wrote:
    >>
    >>>> Since char and unsigned char are different types, you must use either
    >>>> a C-style cast or reinterpret_cast, as you have done. There is really
    >>>> no way to avoid it if you must pass unsigned char to this function.
    >>> You're the second person to state that so I'm interesting in the
    >>> reeasoning.

    >> The reason? Because std::string has no constructor that takes unsigned
    >> char* as an argument.

    >
    > Hm, std::string has a templated constructor:
    >
    >
    > template<class InputIterator>
    > basic_string(InputIterator begin, InputIterator end,
    > const Allocator& a = Allocator());
    >
    >
    > Since unsigned char is convertible to char, this constructor should match.
    >
    >

    There is no coinstructor that takes ONLY an unsigned char* and an
    integral value. He passed a unsigned char* and the integer 12.
    Ron Natalie, Dec 4, 2005
    #17
  18. KK

    Ron Natalie Guest

    Alf P. Steinbach wrote:
    > * Bob Hairgrove:
    >> On Fri, 02 Dec 2005 09:58:35 GMT, (Alf P. Steinbach)
    >> wrote:
    >>
    >>>> Since char and unsigned char are different types, you must use either
    >>>> a C-style cast or reinterpret_cast, as you have done. There is really
    >>>> no way to avoid it if you must pass unsigned char to this function.
    >>> You're the second person to state that so I'm interesting in the
    >>> reeasoning.

    >> The reason? Because std::string has no constructor that takes unsigned
    >> char* as an argument.

    >
    > That is incorrect.


    It is correct.

    >
    Ron Natalie, Dec 4, 2005
    #18
  19. * Ron Natalie:
    > Alf P. Steinbach wrote:
    > > * Bob Hairgrove:
    > >> On Fri, 02 Dec 2005 09:58:35 GMT, (Alf P. Steinbach)
    > >> wrote:
    > >>
    > >>>> Since char and unsigned char are different types, you must use either
    > >>>> a C-style cast or reinterpret_cast, as you have done. There is really
    > >>>> no way to avoid it if you must pass unsigned char to this function.
    > >>> You're the second person to state that so I'm interesting in the
    > >>> reeasoning.
    > >> The reason? Because std::string has no constructor that takes unsigned
    > >> char* as an argument.

    > >
    > > That is incorrect.

    >
    > It is correct.


    Nope.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Dec 4, 2005
    #19
  20. KK

    Guest

    wrote:
    > Bob Hairgrove wrote:
    > > On Fri, 02 Dec 2005 11:04:26 GMT, (Alf P. Steinbach)
    > > wrote:
    > >
    > > >> The reason? Because std::string has no constructor that takes unsigned
    > > >> char* as an argument.
    > > >
    > > >That is incorrect.

    > >
    > > // test_uchar.cpp
    > >
    > > #include <iostream>
    > > #include <ostream>
    > > #include <string>
    > >
    > > int main()
    > > {
    > > const unsigned char msg[] = "Hello";
    > > std::string s(msg);
    > > std::cout << msg << std::endl;
    > > }
    > >
    > > Does that compile on your system?

    >
    > Nope. However, this does:
    >
    > #include <string>
    > const unsigned char msg[] = "Hello";
    > std::string s(msg,msg+sizeof(msg));
    >
    > The statement you're tyring to prove is: "
    > std::string has no constructor that takes one argument, of type
    > unsigned char*.
    > " That statement is of course true, but not really relevant.


    Actually it is pretty obvious that std::string has no constructor that
    takes unsigned char* as an argument just by looking at its
    constructors...none of them take an unsigned char* as an argument. The
    fact that you can pass one as an argument to some of these constructors
    is a consequence of a language feature, mainly that it will
    automatically do some conversions for you. The very important
    distinction here is that unsigned char* is being converted to something
    else, which is then passed as an argument to the function being called;
    in other words no matter how you slice it the constructor is never
    actually given an unsigned char* as it wouldn't accept it.

    Not that I'm not enjoying this "No it doesn't," "Does too," "Does
    not...,"method of arguing. It can be quite entertaining until
    eventually it becomes annoying.
    , Dec 4, 2005
    #20
    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:
    801
    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,621
    Nick Hounsome
    Jan 20, 2004
  3. Alexander Malkis
    Replies:
    8
    Views:
    516
    Alexander Malkis
    Apr 14, 2004
  4. Roger23
    Replies:
    2
    Views:
    994
    Roger23
    Oct 12, 2006
  5. Alex Vinokur
    Replies:
    1
    Views:
    574
Loading...

Share This Page