我正在开发一些有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方法而不会导致约束违规会很好吗?
答案 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)
问题归结为实施定义char
是unsigned
还是signed
。
没有错误的编译器将是char
实际为unsigned
的编译器。其中一些(特别是那些实际上是C ++编译器,其中char
和unsigned char
是不同的类型)将发出警告。使用这些编译器,将指针转换为unsigned char *
将是安全的。
报告错误的编译器将是char
实际为signed
的编译器。如果编译器(或主机)使用ASCII或类似字符集,并且字符串中的字符是可打印的,则将字符串转换为unsigned char *
(或者更好地转换为const unsigned char *
,这样可以避免丢弃const
1}}来自字符串文字)在技术上是安全的。但是,对于使用不同字符集的实现,或者对于包含不可打印字符的字符串(例如,类型为signed char
的值为负值,且unsigned char
的值大于127),这些转换可能不安全。我说可能不安全,因为发生的事情取决于被调用函数的作用 - 例如它是否检查单个字符的值?它会检查字符串中各个字符的各个位吗?如果被调用的函数设计得很好,后者就是接受指向unsigned char *
的指针的一个原因。
因此,您需要做的是关于目标机器及其char
和unsigned char
类型 - 以及函数对其参数的作用。最通用的方法(在某种意义上它适用于所有字符集,无论char
是signed
还是unsigned
)都是创建一个辅助函数来复制{的数组{1}}到char
的其他数组。该辅助函数的工作将取决于您需要如何(以及如果)处理unsigned char
值的转换为负值。