首页 文章

如何避免gcc警告简单的“char”:“unsigned char”或“signed char”转换?

提问于
浏览
3

我的默认字符类型是gcc选项(-funsigned-char gcc)中设置的“unsigned char” . 所以当我在代码中需要“unsigned char”时,我可以使用“char” . 但我收到警告(char *)和(unsigned char *或signed char *)之间的转换:

"error: pointer targets in passing argument 1 of 'test2' differ in signedness" .

当我将unsigned char *变量传递给char *时,我怎么能避免警告(知道我的syetem有编译器选项设置的默认unsigned char)?

static void test2(char* a)      //char is unsigned by deafult as set by -funsigned-char gcc option
{
}

void    test1(void)
{
        // This passes, but if i change it to unsigned char (or 'signed char') it fails   
        // I dont want it to fail for "unsigned char c" since default char is unsigned.
        char    c = 65; 
        test2(&c);
}

4 回答

  • 2

    开关 -funsigned-char-fsigned-char 不是指 char * .

    您可以使用 -Wno-pointer-sign 关闭收到的警告 .

  • 3

    使用演员表:

    char c = 65;   // weird magic :-(
    
    test2((unsigned char *)(&c));
    

    所有char类型都是布局兼容的,并且转换它们的指针不构成类型惩罚或违反别名规则,因此您可以自由地执行此操作 .

  • 5

    正确的解决方案是将正确类型的变量传递给函数,即如果函数需要普通的char,则声明一个普通的char并获取其地址,依此类推 .

    C标准说“char”,“signed char”和“unsigned char”是不同的类型 . “char”必须与“signed char”或“unsigned char”具有相同的行为,由编译器开关确定,但您不能互换使用它们 . 无论是否使用-funsigned-char,您都应该编写完全相同的代码 .

    另一张海报使用演员表的建议并不好 . 所有这一切都是抑制警告,明确禁用警告(例如使用pragma,或在makefile中全局关闭警告)会更清楚 .

    强制转换不能解决代码问题,它只是阻止编译器指出它 . 这是一个稍微学术性的观点,但在非2的补码系统中,有符号的字符可能有陷阱表示(它们的布局兼容值0 <= x <= CHAR_MAX而不是其他值) . 所以代码可能会崩溃 .

    根据您提供的详细信息,实际上您最好的解决方案可能只是禁用警告,并且在这方面代码是不可移植的 .

  • 1

    最后我得到了答案:

    -Wall和-pedantic暗示了-Wpointer-sign . 为避免警告使用-Wno-pointer-sign

相关问题