开发者

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));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜