我有以下代码:
#include <stdlib.h>
#include <stdio.h>
void test(unsigned char * arg) { }
int main() {
char *pc = (char *) malloc(1);
unsigned char *pcu = (unsigned char *) malloc(1);
*pcu = *pc = -1; /* line 10 */
if (*pc == *pcu) puts("equal"); else puts("not equal"); /* line 12 */
pcu = pc; /* line 14 */
if (pcu == pc) { /* line 16 */
test(pc); /* line 18 */
}
return 0;
}
如果我使用gcc版本4.6.3(Ubuntu / Linaro 4.6.3-1ubuntu5)编译它(但不限于此特定版本)并带有选项
gcc a.c -pedantic -Wall -Wextra -Wsign-conversion -Wno-unused-parameter; ./a.out
我收到以下警告
test.c: In function ‘main’:
test.c:10:21: warning: conversion to ‘unsigned char’ from ‘char’ may change the sign of the result [-Wsign-conversion]
test.c:14:13: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
test.c:16:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
test.c:18:17: warning: pointer targets in passing argument 1 of ‘test’ differ in signedness [-Wpointer-sign]
test.c:4:6: note: expected ‘unsigned char *’ but argument is of type ‘char *’
not equal
g ++警告/错误类似。我希望我理解为什么第12行的比较被评估为 false ,但在这种情况下是否有任何方法可以获得警告?如果没有,第12行和导致警告的行之间是否存在一些主要区别?有没有具体的理由为什么char和unsigned char的比较不应该得到它的警告?因为至少乍一看,第12行对我来说比“危险”更“危险”。第16行。
一个简短的“故事背后”:我必须将各种来源的代码拼凑起来。其中一些使用char,其中一些使用unsigned char。 -funsigned-char
可以正常工作,但我不得不避免使用它,而是添加正确的类型转换。这就是为什么这样的警告对我有用,因为现在,如果我忘记在这种情况下添加类型转换,程序会默默地失败。
提前致谢,P。
答案 0 :(得分:0)
我认为这是由整数提升引起的。
当您处理char
或short
时,C实际执行的操作(这是由标准定义的,而不是实现)是在执行任何操作之前将这些类型提升为int
。我认为,理论认为int
应该是底层机器使用的自然尺寸,因此是最快,最有效的尺寸;事实上,大多数架构都会在没有被问到的情况下加载一个字节进行这种转换。
由于signed char
和unsigned char
都适合signed int
的范围,编译器会将其用于两者,并且比较变为纯签名比较
如果表达式左侧的类型不匹配(第10行和第14行),则需要将其转换回较小的类型,但它不能,因此您会收到警告。< / p>
当您比较不匹配指针(第16行)并传递不匹配指针(第18行)时,整数提升不起作用,因为您实际上从未取消引用指针,因此不会比较整数({{1}当然也是整数类型。