如何使gcc / g ++在比较signed和unsigned char时发出警告

时间:2013-11-14 11:12:16

标签: gcc

我有以下代码:

#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。

1 个答案:

答案 0 :(得分:0)

我认为这是由整数提升引起的。

当您处理charshort时,C实际执行的操作(这是由标准定义的,而不是实现)是在执行任何操作之前将这些类型提升为int 。我认为,理论认为int应该是底层机器使用的自然尺寸,因此是最快,最有效的尺寸;事实上,大多数架构都会在没有被问到的情况下加载一个字节进行这种转换。

由于signed charunsigned char都适合signed int的范围,编译器会将其用于两者,并且比较变为纯签名比较

如果表达式左侧的类型不匹配(第10行和第14行),则需要将其转换回较小的类型,但它不能,因此您会收到警告。< / p>

当您比较不匹配指针(第16行)并传递不匹配指针(第18行)时,整数提升不起作用,因为您实际上从未取消引用指针,因此不会比较整数({{1}当然也是整数类型。