3

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

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

当我将 unsigned char* 变量传递给 char* 时,如何避免警告(知道我的系统具有编译器选项设置的默认 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

4 回答 4

7

开关-funsigned-char-fsigned-char没有参考char *

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

于 2012-11-15T15:50:32.547 回答
3

正确的解决方案是将正确类型的变量传递给函数,即如果函数需要纯字符,则声明纯字符并获取其地址,依此类推。

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

另一张海报使用演员表的建议并不好。所做的只是抑制警告,明确禁用警告会更清楚(例如,使用编译指示,或在您的生成文件中全局关闭警告)。

演员表并没有解决代码的问题,它只是阻止编译器指出它。这是一个有点学术的观点,但在非 2 的补码系统上,带符号的字符可能有陷阱表示(它们与值 0 <= x <= CHAR_MAX 但不是其他值的布局兼容)。所以代码可能会崩溃。

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

于 2013-08-12T22:26:17.307 回答
3

使用演员表:

char c = 65;   // weird magic :-(

test2((unsigned char *)(&c));

所有 char 类型都是布局兼容的,并且转换它们的指针不构成类型双关语或违反别名规则,因此您可以自由地这样做。

于 2012-11-15T15:28:45.907 回答
1

最后我得到了答案:

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

于 2012-11-15T15:49:39.307 回答