Connecting Tech Pros Worldwide Help | Site Map

how to avoid reinterpret_cast in this snippet?

 
LinkBack Thread Tools Search this Thread
  #1  
Old December 1st, 2005, 09:55 PM
KK
Guest
 
Posts: n/a
Default how to avoid reinterpret_cast in this snippet?

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


  #2  
Old December 1st, 2005, 10:05 PM
Ron Natalie
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

KK wrote:[color=blue]
> 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;
> }
>[/color]
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.
  #3  
Old December 1st, 2005, 10:15 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* KK:[color=blue]
> 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;
> }[/color]

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?
  #4  
Old December 1st, 2005, 11:55 PM
ben
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

KK wrote:[color=blue]
> 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;
> }
>[/color]


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

  #5  
Old December 2nd, 2005, 12:35 AM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* ben:[color=blue]
> KK wrote:[color=green]
> > 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;
> > }
> >[/color]
>
>
> 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());[/color]

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

I'd write

s.assign( buffer, buffer+12 );
[color=blue]
> }
>
> BYTE buff[19];
> int pos = 6;
> std::string str;[/color]

Oops... ;-)

[color=blue]
> GetStringFromByteBuffer(
> buff + pos,
> str);[/color]

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?
  #6  
Old December 2nd, 2005, 08:35 AM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On 1 Dec 2005 14:47:10 -0800, "KK" <kewlkarun@yahoo.com> wrote:
[color=blue]
>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;
>}[/color]

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
NoSpamPlease@Home.com
  #7  
Old December 2nd, 2005, 09:05 AM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Bob Hairgrove:[color=blue]
> On 1 Dec 2005 14:47:10 -0800, "KK" <kewlkarun@yahoo.com> wrote:
>[color=green]
> >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;
> >}[/color]
>
> 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.[/color]

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?
  #8  
Old December 2nd, 2005, 09:15 AM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (Alf P. Steinbach)
wrote:
[color=blue][color=green]
>> 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.[/color]
>
>You're the second person to state that so I'm interesting in the
>reeasoning.[/color]

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
NoSpamPlease@Home.com
  #9  
Old December 2nd, 2005, 09:55 AM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Bob Hairgrove wrote:
[color=blue]
> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (Alf P. Steinbach)
> wrote:
>[color=green][color=darkred]
>>> 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.[/color]
>>
>>You're the second person to state that so I'm interesting in the
>>reeasoning.[/color]
>
> The reason? Because std::string has no constructor that takes unsigned
> char* as an argument.[/color]

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
  #10  
Old December 2nd, 2005, 10:15 AM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Bob Hairgrove:[color=blue]
> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (Alf P. Steinbach)
> wrote:
>[color=green][color=darkred]
> >> 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.[/color]
> >
> >You're the second person to state that so I'm interesting in the
> >reeasoning.[/color]
>
> The reason? Because std::string has no constructor that takes unsigned
> char* as an argument.[/color]

That is incorrect.
[color=blue]
> (And I believe that there are more than two others by now... ;)[/color]

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?
  #11  
Old December 2nd, 2005, 12:15 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Fri, 02 Dec 2005 05:31:13 -0500, Kai-Uwe Bux <jkherciueh@gmx.net>
wrote:
[color=blue]
>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.[/color]

// 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
NoSpamPlease@Home.com
  #12  
Old December 2nd, 2005, 12:15 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Fri, 02 Dec 2005 11:04:26 GMT, alfps@start.no (Alf P. Steinbach)
wrote:
[color=blue][color=green]
>> The reason? Because std::string has no constructor that takes unsigned
>> char* as an argument.[/color]
>
>That is incorrect.[/color]

// 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
NoSpamPlease@Home.com
  #13  
Old December 2nd, 2005, 12:35 PM
Michiel.Salters@tomtom.com
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?


Bob Hairgrove wrote:[color=blue]
> On Fri, 02 Dec 2005 11:04:26 GMT, alfps@start.no (Alf P. Steinbach)
> wrote:
>[color=green][color=darkred]
> >> The reason? Because std::string has no constructor that takes unsigned
> >> char* as an argument.[/color]
> >
> >That is incorrect.[/color]
>
> // 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?[/color]

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

  #14  
Old December 2nd, 2005, 12:45 PM
Neil Cerutti
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On 2005-12-02, Bob Hairgrove <invalid@bigfoot.com> wrote:[color=blue]
> On Fri, 02 Dec 2005 11:04:26 GMT, alfps@start.no (Alf P. Steinbach)
> wrote:
>[color=green][color=darkred]
>>> The reason? Because std::string has no constructor that takes unsigned
>>> char* as an argument.[/color]
>>
>>That is incorrect.[/color]
>
> // 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
> NoSpamPlease@Home.com[/color]


--
Neil Cerutti
  #15  
Old December 2nd, 2005, 01:25 PM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Bob Hairgrove wrote:
[color=blue]
> On Fri, 02 Dec 2005 05:31:13 -0500, Kai-Uwe Bux <jkherciueh@gmx.net>
> wrote:
>[color=green]
>>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.[/color]
>
> // 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?[/color]

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
  #16  
Old December 2nd, 2005, 05:55 PM
Neil Cerutti
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On 2005-12-02, Neil Cerutti <leadvoice@email.com> wrote:[color=blue]
> On 2005-12-02, Bob Hairgrove <invalid@bigfoot.com> wrote:[color=green]
>> On Fri, 02 Dec 2005 11:04:26 GMT, alfps@start.no (Alf P.
>> Steinbach) wrote:[color=darkred]
>>>> The reason? Because std::string has no constructor that
>>>> takes unsigned char* as an argument.
>>>
>>>That is incorrect.[/color]
>>
>> // 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?[/color][/color]

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
  #17  
Old December 4th, 2005, 07:15 PM
Ron Natalie
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Kai-Uwe Bux wrote:[color=blue]
> Bob Hairgrove wrote:
>[color=green]
>> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (Alf P. Steinbach)
>> wrote:
>>[color=darkred]
>>>> 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.[/color]
>> The reason? Because std::string has no constructor that takes unsigned
>> char* as an argument.[/color]
>
> 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.
>
>[/color]
There is no coinstructor that takes ONLY an unsigned char* and an
integral value. He passed a unsigned char* and the integer 12.
  #18  
Old December 4th, 2005, 07:15 PM
Ron Natalie
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Alf P. Steinbach wrote:[color=blue]
> * Bob Hairgrove:[color=green]
>> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (Alf P. Steinbach)
>> wrote:
>>[color=darkred]
>>>> 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.[/color]
>> The reason? Because std::string has no constructor that takes unsigned
>> char* as an argument.[/color]
>
> That is incorrect.[/color]

It is correct.
[color=blue]
>[/color]
  #19  
Old December 4th, 2005, 07:15 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Ron Natalie:[color=blue]
> Alf P. Steinbach wrote:[color=green]
> > * Bob Hairgrove:[color=darkred]
> >> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (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.[/color]
> >
> > That is incorrect.[/color]
>
> It is correct.[/color]

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?
  #20  
Old December 4th, 2005, 07:35 PM
roberts.noah@gmail.com
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?


Michiel.Salters@tomtom.com wrote:[color=blue]
> Bob Hairgrove wrote:[color=green]
> > On Fri, 02 Dec 2005 11:04:26 GMT, alfps@start.no (Alf P. Steinbach)
> > wrote:
> >[color=darkred]
> > >> The reason? Because std::string has no constructor that takes unsigned
> > >> char* as an argument.
> > >
> > >That is incorrect.[/color]
> >
> > // 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?[/color]
>
> 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.[/color]

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.

  #21  
Old December 4th, 2005, 07:45 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* roberts.noah@gmail.com:[color=blue]
>
>
> 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,[/color]

No, it isn't.

--
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?
  #22  
Old December 4th, 2005, 08:55 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Fri, 02 Dec 2005 09:05:31 -0500, Kai-Uwe Bux <jkherciueh@gmx.net>
wrote:
[color=blue]
>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;
>}[/color]

Not on my machine:

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test_uchar.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: Unresolved external 'std::basic_string<char,
std::char_traits<char>, std::allocator<char> >::basic_string<char,
std::char_traits<char>, std::allocator<char> >(const unsigned char *,
const unsigned char *, const std::allocator<char>&)' referenced from
E:\TEST_UCHAR.OBJ

--
Bob Hairgrove
NoSpamPlease@Home.com
  #23  
Old December 4th, 2005, 09:05 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On 2 Dec 2005 05:23:54 -0800, Michiel.Salters@tomtom.com wrote:
[color=blue]
>Nope. However, this does:
>
>#include <string>
>const unsigned char msg[] = "Hello";
>std::string s(msg,msg+sizeof(msg));[/color]

Not on my machine:

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test_uchar.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: Unresolved external 'std::basic_string<char,
std::char_traits<char>, std::allocator<char> >::basic_string<char,
std::char_traits<char>, std::allocator<char> >(const unsigned char *,
const unsigned char *, const std::allocator<char>&)
' referenced from E:\TEST_UCHAR.OBJ

--
Bob Hairgrove
NoSpamPlease@Home.com
  #24  
Old December 4th, 2005, 09:05 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Sun, 04 Dec 2005 22:48:59 +0100, Bob Hairgrove
<invalid@bigfoot.com> wrote:
[color=blue]
>On Fri, 02 Dec 2005 09:05:31 -0500, Kai-Uwe Bux <jkherciueh@gmx.net>
>wrote:
>[color=green]
>>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;
>>}[/color]
>
>Not on my machine:
>
>Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
>test_uchar.cpp:
>Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
>Error: Unresolved external 'std::basic_string<char,
>std::char_traits<char>, std::allocator<char> >::basic_string<char,
>std::char_traits<char>, std::allocator<char> >(const unsigned char *,
>const unsigned char *, const std::allocator<char>&)' referenced from
>E:\TEST_UCHAR.OBJ[/color]

OK -- it compiles, but it doesn't link because Borland provides no
*compiler magic* to make it work.

--
Bob Hairgrove
NoSpamPlease@Home.com
  #25  
Old December 4th, 2005, 09:05 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Sun, 04 Dec 2005 22:49:59 +0100, Bob Hairgrove
<invalid@bigfoot.com> wrote:
[color=blue]
>On 2 Dec 2005 05:23:54 -0800, Michiel.Salters@tomtom.com wrote:
>[color=green]
>>Nope. However, this does:
>>
>>#include <string>
>>const unsigned char msg[] = "Hello";
>>std::string s(msg,msg+sizeof(msg));[/color]
>
>Not on my machine:
>
>Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
>test_uchar.cpp:
>Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
>Error: Unresolved external 'std::basic_string<char,
>std::char_traits<char>, std::allocator<char> >::basic_string<char,
>std::char_traits<char>, std::allocator<char> >(const unsigned char *,
>const unsigned char *, const std::allocator<char>&)
>' referenced from E:\TEST_UCHAR.OBJ[/color]

OK -- it compiles, but it doesn't link because Borland provides no
*compiler magic* to make it work.

--
Bob Hairgrove
NoSpamPlease@Home.com
  #26  
Old December 4th, 2005, 09:55 PM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Ron Natalie wrote:
[color=blue]
> Kai-Uwe Bux wrote:[color=green]
>> Bob Hairgrove wrote:
>>[color=darkred]
>>> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (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.[/color]
>>
>> 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.
>>
>>[/color]
> There is no coinstructor that takes ONLY an unsigned char* and an
> integral value. He passed a unsigned char* and the integer 12.[/color]

True, but utterly irrelevant:

May I remind you of the original post:
[color=blue]
> 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 +[/color]
pos);[color=blue]
> std::string tmp(chAry,12);
> return chAry;
> }[/color]

The operative phrase being "*how* can I avoid...", the OP asks about a way
to implement GetStringFromBuffer that avoids casts. This clearly can be
done using the templated std::string constructor I mentioned. The following
solution is essentially stolen from Alf Steinbach's post:

std::string GetStringFromByteBuffer(const BYTE* const buffer, int pos )
{
return std::string( buffer+pos, buffer+pos+12 );
}

This fits the specs given by the OP. The claim that "there is really no way
to avoid it [casting] if you must pass unsigned char to this function" is
therefore false. The line "Because std::string has no constructor that
takes unsigned char* as an argument" was given as a reason, and since it
tries to argue something false, it is false itself or fails to imply what
it is supposed to argue. Make your pick: if you read it as narrow as

std::string ( unsigned char*, int ) is not valid

then it fails to imply what it is supposed to argue; if you use a broader
reading, the statement will become false.


Best

Kai-Uwe Bux
  #27  
Old December 5th, 2005, 12:15 AM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Bob Hairgrove:[color=blue]
> On Sun, 04 Dec 2005 22:49:59 +0100, Bob Hairgrove
> <invalid@bigfoot.com> wrote:
>[color=green]
> >On 2 Dec 2005 05:23:54 -0800, Michiel.Salters@tomtom.com wrote:
> >[color=darkred]
> >>Nope. However, this does:
> >>
> >>#include <string>
> >>const unsigned char msg[] = "Hello";
> >>std::string s(msg,msg+sizeof(msg));[/color]
> >
> >Not on my machine:
> >
> >Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
> >test_uchar.cpp:
> >Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
> >Error: Unresolved external 'std::basic_string<char,
> >std::char_traits<char>, std::allocator<char> >::basic_string<char,
> >std::char_traits<char>, std::allocator<char> >(const unsigned char *,
> >const unsigned char *, const std::allocator<char>&)
> >' referenced from E:\TEST_UCHAR.OBJ[/color]
>
> OK -- it compiles, but it doesn't link because Borland provides no
> *compiler magic* to make it work.[/color]

Try

bcc32 -D"_RWSTD_COMPILE_INSTANTIATE" -w-ccc -w-rch test_uchar.cpp

Hth.,

- Alf


PS: I recommend using some other free compiler, e.g. g++ or MSVC; <url:
http://home.no.net/dubjai/win32cpptut/html/w32cpptut_01_01_02.html>.

--
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?
  #28  
Old December 5th, 2005, 03:35 AM
Old Wolf
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Bob Hairgrove wrote:
[color=blue]
> Michiel.Salters@tomtom.com wrote:
>[color=green]
>>#include <string>
>>const unsigned char msg[] = "Hello";
>>std::string s(msg,msg+sizeof(msg));[/color]
>
> Not on my machine:
>
> Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
> test_uchar.cpp:
> Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
> Error: Unresolved external 'std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >::basic_string<char,
> std::char_traits<char>, std::allocator<char> >(const unsigned char *,
> const unsigned char *, const std::allocator<char>&)[/color]

That's a bug in the standard library supplied with Borland C++.
The body of the constructor is never defined.
My workaround is to avoid using that constructor.

  #29  
Old December 5th, 2005, 04:05 AM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Old Wolf:[color=blue]
> Bob Hairgrove wrote:
>[color=green]
> > Michiel.Salters@tomtom.com wrote:
> >[color=darkred]
> >>#include <string>
> >>const unsigned char msg[] = "Hello";
> >>std::string s(msg,msg+sizeof(msg));[/color]
> >
> > Not on my machine:
> >
> > Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
> > test_uchar.cpp:
> > Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
> > Error: Unresolved external 'std::basic_string<char,
> > std::char_traits<char>, std::allocator<char> >::basic_string<char,
> > std::char_traits<char>, std::allocator<char> >(const unsigned char *,
> > const unsigned char *, const std::allocator<char>&)[/color]
>
> That's a bug in the standard library supplied with Borland C++.
> The body of the constructor is never defined.
> My workaround is to avoid using that constructor.[/color]

See my reply to the same posting -- the constructor body is defined in
a file that is conditionally included by <string>.

I suspect there is also a way to link a compiled version of that file,
using some language extension (doing the job of 'export'), but, it's an
old compiler, so I don't care to use the time to find out.

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?
  #30  
Old December 5th, 2005, 07:05 PM
Bob Hairgrove
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

On Mon, 05 Dec 2005 01:06:01 GMT, alfps@start.no (Alf P. Steinbach)
wrote:
[color=blue]
>Try
>
> bcc32 -D"_RWSTD_COMPILE_INSTANTIATE" -w-ccc -w-rch test_uchar.cpp
>
>Hth.,[/color]

No, it doesn't really "help" (HTH == "hope this helps") <g>

The basic question remains:
Is it *required* by the C++ standard that your code compiles (and
links)? And if you think so, please explain why (and not just: "it
does").

[I hope you realize that the above "hack" can create serious problems
with code that is distributed among different DLLs which rely on
things defined in the DLLs supplied by Borland (e.g., anything even
remotely depending on VCL)?]

--
Bob Hairgrove
NoSpamPlease@Home.com
  #31  
Old December 5th, 2005, 08:05 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Bob Hairgrove:[color=blue]
> On Mon, 05 Dec 2005 01:06:01 GMT, alfps@start.no (Alf P. Steinbach)
> wrote:
>[color=green]
> >Try
> >
> > bcc32 -D"_RWSTD_COMPILE_INSTANTIATE" -w-ccc -w-rch test_uchar.cpp
> >
> >Hth.,[/color]
>
> No, it doesn't really "help" (HTH == "hope this helps") <g>
>
> The basic question remains:
> Is it *required* by the C++ standard that your code compiles (and
> links)?[/color]

Yes, but not that it "works". The working aspect is covered by
conversion from unsigned char to char (not pointers but values). And
this value conversion, although in-practice well-defined on all modern
platforms, is formally undefined behavior language-wise.

To make more sure that it works, not just compiles and links, one would
have to include a compile time assertion like

static unsigned char const polyanna = 156; // Say.
BOOST_STATIC_ASSERT(
static_cast<unsigned char>( static_cast<char>( polyanna ) ) ==
polyanna
);

And add the assumption that the original data consists of char values
casted to unsigned char -- but I think that borders on the ludicrious.

[color=blue]
> And if you think so, please explain why (and not just: "it
> does").[/color]

By definition of the templated std::basic_string constructor, which is
required to copy the values.

[color=blue]
> [I hope you realize that the above "hack" can create serious problems
> with code that is distributed among different DLLs which rely on
> things defined in the DLLs supplied by Borland (e.g., anything even
> remotely depending on VCL)?][/color]

No, I didn't realize that, and I don't know that, and it isn't a hack,
it's a compiler invocation. It sounds improbable. But, it's an old
compiler and I don't really care about its undocumented features. ;-)

Hth.,

- 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?
  #32  
Old December 5th, 2005, 11:15 PM
Ron Natalie
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

Alf P. Steinbach wrote:[color=blue]
> * Ron Natalie:[color=green]
>> Alf P. Steinbach wrote:[color=darkred]
>>> * Bob Hairgrove:
>>>> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (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.[/color]
>> It is correct.[/color]
>
> Nope.
>[/color]
There is NO constructor that takes ONLY a unsigned char* (or even
an unsigned char* and a integer like the OP's original intended use).

  #33  
Old December 5th, 2005, 11:25 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: how to avoid reinterpret_cast in this snippet?

* Ron Natalie:[color=blue]
> Alf P. Steinbach wrote:[color=green]
> > * Ron Natalie:[color=darkred]
> >> Alf P. Steinbach wrote:
> >>> * Bob Hairgrove:
> >>>> On Fri, 02 Dec 2005 09:58:35 GMT, alfps@start.no (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.[/color]
> >
> > Nope.
> >[/color]
> There is NO constructor that takes ONLY a unsigned char* (or even
> an unsigned char* and a integer like the OP's original intended use).[/color]

So?

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

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,662 network members.