将char *传递给期望unsigned char *

时间:2015-05-29 19:01:27

标签: c

我正在开发一些有SDK的嵌入式设备。它有一个方法:

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

但我在他们的例子中看到调用代码如:

MessageBox("hi","hello");

传递char指针而不进行强制转换。这可以定义好吗?我问,因为我在代码上运行了一些工具,它抱怨上面的不匹配:

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)

<小时/> 有时我对这个答案有不同的看法,这让我更加困惑。总结一下,通过上面描述的方式使用他们的API,这个问题是什么?它会破坏程序吗?

并且听听正确的方式然后将字符串传递给期望unsigned char*的SDK方法而不会导致约束违规会很好吗?

2 个答案:

答案 0 :(得分:3)

这是一种约束违规,所以从技术上讲它没有很好的定义,但在实践中,它不是一个问题。然而,你应该抛出这些论点来压制这些警告。使用丑陋的强制转换乱丢代码的另一种方法是定义内联函数:

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

并且在需​​要将字符串传递给API(错误地)接受unsigned char *参数的地方时使用该函数:

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

这样,在保持某种类型安全的同时,您不会收到警告。

另请注意,messageBox应该使用const char *个参数。此SDK使用可疑的约定。

答案 1 :(得分:0)

问题归结为实施定义charunsigned还是signed

没有错误的编译器将是char实际为unsigned的编译器。其中一些(特别是那些实际上是C ++编译器,其中charunsigned char是不同的类型)将发出警告。使用这些编译器,将指针转换为unsigned char *将是安全的。

报告错误的编译器将是char实际为signed的编译器。如果编译器(或主机)使用ASCII或类似字符集,并且字符串中的字符是可打印的,则将字符串转换为unsigned char *(或者更好地转换为const unsigned char *,这样可以避免丢弃const 1}}来自字符串文字)在技术上是安全的。但是,对于使用不同字符集的实现,或者对于包含不可打印字符的字符串(例如,类型为signed char的值为负值,且unsigned char的值大于127),这些转换可能不安全。我说可能不安全,因为发生的事情取决于被调用函数的作用 - 例如它是否检查单个字符的值?它会检查字符串中各个字符的各个位吗?如果被调用的函数设计得很好,后者就是接受指向unsigned char *的指针的一个原因。

因此,您需要做的是关于目标机器及其charunsigned char类型 - 以及函数对其参数的作用。最通用的方法(在某种意义上它适用于所有字符集,无论charsigned还是unsigned)都是创建一个辅助函数来复制{的数组{1}}到char的其他数组。该辅助函数的工作将取决于您需要如何(以及如果)处理unsigned char值的转换为负值。