Pass char* to method expecting unsigned char*

I am working on some embedded device which has SDK. It has a method like:

MessageBox(u8*, u8*); // u8 is typedefed unsigned char when I checked

But I have seen in their examples calling code like:

MessageBox("hi","hello");

passing char pointer without cast. Can this be well defined? I am asking because I ran some tool over the code, and it was complaining about above mismatch:

messageBox("Status", "Error calculating rhash");
diy.c  89  Error 64:  Type mismatch (arg. no. 1) (ptrs to signed/unsigned)
diy.c  89  Error 64:  Type mismatch (arg. no. 2) (ptrs to signed/unsigned)


Sometimes I get different opinions on this answer and this confuses me even more. So to sum up, by using their API the way described above, is this problem? Will it crash the program?

And also it would be nice to hear what is the correct way then to pass string to SDK methods expecting unsigned char* without causing constraint violation?


It is a constraint violation, so technically it is not well defined, but in practice, it is not a problem. Yet you should cast these arguments to silence these warnings. An alternative to littering your code with ugly casts is to define an inline function:

static inline unsigned char *ucstr(const char *str) { return (unsigned char *)str; }

And use that function wherever you need to pass strings to the APIs that (mistakenly) take unsigned char * arguments:

messageBox(ucstr("hi"), ucstr("hello"));

This way you will not get warnings while keeping some type safety.

Also note that messageBox should take const char * arguments. This SDK uses questionable conventions.


The problem comes down to it being implementation-defined whether char is unsigned or signed .

Compilers for which there is no error will be those for which char is actually unsigned . Some of those (notably the ones that are actually C++ compilers, where char and unsigned char are distinct types) will issue a warning. With these compilers, converting the pointer to unsigned char * will be safe.

Compilers which report an error will be those for which char is actually signed . If the compiler (or host) uses an ASCII or similar character set, and the characters in the string are printable, then converting the string to unsigned char * (or, better, to const unsigned char * which avoids dropping const ness from string literals) is technically safe. However, those conversions are potentially unsafe for implementations that use different character sets OR for strings that contain non-printable characters (eg values of type signed char that are negative, and values of unsigned char greater than 127). I say potentially unsafe, because what happens depends on what the called function does - for example does it check the values of individual characters? does it check the individual bits of individual characters in the string? The latter is, if the called function is well designed, one reason it will accept a pointer to unsigned char * .

What you need to do therefore comes down to what you can assume about the target machine, and its char and unsigned char types - and what the function is doing with its argument. The most general approach (in the sense that it works for all character sets, and regardless of whether char is signed or unsigned ) is to create a helper function which copies the array of char to a different array of unsigned char . The working of that helper function will depend on how (and if) you need to handle the conversion of signed char values with values that are negative.

链接地址: http://www.djcxy.com/p/26714.html

上一篇: 如何在关闭期间保存页面状态

下一篇: 将char *传递给期望unsigned char的方法*