how to avoid reinterpret_cast in this snippet?

K

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

Ron Natalie

KK said:
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.
 
A

Alf P. Steinbach

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

ben

KK said:
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
 
A

Alf P. Steinbach

* ben:
KK said:
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...
 
B

Bob Hairgrove

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

Alf P. Steinbach

* Bob Hairgrove:
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.
 
B

Bob Hairgrove

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... ;)
 
K

Kai-Uwe Bux

Bob said:
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
 
A

Alf P. Steinbach

* Bob Hairgrove:
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
 
B

Bob Hairgrove

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

Bob Hairgrove

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

Michiel.Salters

Bob said:
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
 
N

Neil Cerutti

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

Kai-Uwe Bux

Bob said:
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
 
N

Neil Cerutti

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

Ron Natalie

Kai-Uwe Bux said:
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.
 
R

roberts.noah

Bob said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top