首页 文章

如何使gcc / g警告比较signed和unsigned char

提问于
浏览
1

我有以下代码:

#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行的比较被评估为假,但在这种情况下是否有任何方法可以得到警告?如果没有,第12行和导致警告的行之间是否存在一些主要区别?有没有具体的理由为什么char和unsigned char的比较不值得发出警告?因为至少乍一看,第12行似乎比我更多"dangerous"第16行 .

简短"story behind":我必须将各种来源的代码拼凑起来 . 其中一些使用char,其中一些使用unsigned char . -funsigned-char 会正常工作,但我不得不避免它,而是添加正确的类型转换 . 这就是为什么这样的警告对我有用,因为现在,如果我忘记在这种情况下添加类型转换,程序将默默地失败 .

提前谢谢,P .

1 回答

  • 0

    我相信这是整数推广引起的 .

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

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

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

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

相关问题