C code in C++ compiler
I have following code, it's code from tomcrypto's manual and it won't work on MS VC++ 2008 EE. Any help? Also can I ask replace char*
by std::string
object?
int main(void)
{
hash_state md;
unsigned char *in = "hello world", out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_process(&md, in, strlen(in));
/* get the hash in out[0..15] */
md5_done(&md, out);
return 0;
}
Errors:
\main.cpp(7) : error C2440: 'initializing' : cannot convert from 'const char [12]' to 'unsigned char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
.\main.cpp(11) : error C2664: 'strlen' : cannot convert parameter 1 from 'unsigned char *' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
EDIT: Now code looks like:
int main(void)
{
register_hash(&md5_desc);
hash_state md;
char* p = "hello wordl";
unsigned char *in = reinterpret_cast<unsigned char*>(p);
char* out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_p开发者_开发技巧rocess(&md, const_cast<char*>(in), strlen(in));
/* get the hash in out[0..15] */
md5_done(&md, out);
return 0;
}
Errors:
\main.cpp(21) : error C2440: 'const_cast' : cannot convert from 'unsigned char *' to 'char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
.\main.cpp(21) : error C2664: 'strlen' : cannot convert parameter 1 from 'unsigned char *' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
.\main.cpp(23) : error C2664: 'md5_done' : cannot convert parameter 2 from 'char *[16]' to 'unsigned char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
unsigned char *in = "hello world"
This is incorrect in C++: "hello world"
is a string literal and is of type const char[12]
. In C it is of type char[12]
, but the const
here doesn't matter because in C++ there is an implicit (but deprecated) conversion that allows a string literal to be converted to a char*
.
The problem is that char
and unsigned char
are different types. It doesn't matter whether char
is unsigned; the three char
types (char
, unsigned char
, and signed char
) are all distinct and in C++ you cannot convert between pointers to those three types without a cast.
This works in C because in C you can convert any pointer-to-object type to any other pointer-to-object type without a cast. That isn't the case in C++.
In C++ you would need to use:
// use the implicit conversion to 'char*' to cast away constness:
char* p = "hello world";
// explicitly cast to 'unsigned char*'
unsigned char* in = reinterpret_cast<unsigned char*>(p);
The removal of constness is usually a bad idea since string literals are not modifiable, but sometimes it is necessary when dealing with legacy libraries that are not const-correct.
The conversion from char*
to unsigned char*
is safe because all objects can be treated as an array of char
, unsigned char
, or signed char
in C++.
char
is a different type to signed char
or unsigned char
; string literals are always of type (const) char *
; so you cannot assign them to a (const) signed char *
or a (const) unsigned char *
. To fix this, remove the unsigned
from line 4.
If your md5_process()
function explicitly takes an unsigned char *
as an argument, then you should perform a cast at that point:
md5_process(&md, reinterpret_cast<unsigned char*>(in), strlen(in));
[As others have said, you should really define in
as const char *in
as it's pointing to a string literal, but that is not the issue here.]
Let's try again:
int main(void)
{
register_hash(&md5_desc);
hash_state md;
const char* p = "hello wordl";
const unsigned char* in = reinterpret_cast<const unsigned char*>(p);
unsigned char out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_process(&md, in, strlen(p));
/* get the hash in out[0..15] */
md5_done(&md, out);
return 0;
}
Does this work?
This is because litteral strings are const in C++, while you initialize it with a non-const pointer:
const char* in = "hello world";
char * out[16];
However it might cause a problem if md5_process takes a non-const char*
, in this case you'll have to cast to a non-const:
md5_process(&md, const_cast<char*>(in), strlen(in));
精彩评论