我的默认字符类型是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);
}
答案 0 :(得分:6)
交换机-funsigned-char
和-fsigned-char
未引用char *
。
您可以使用-Wno-pointer-sign
关闭收到的警告。
答案 1 :(得分:3)
使用演员:
char c = 65; // weird magic :-(
test2((unsigned char *)(&c));
所有字符类型都是布局兼容的,并且投射它们的指针不构成类型处罚或违反别名规则,因此您可以自由地执行此操作。
答案 2 :(得分:2)
正确的解决方案是将正确类型的变量传递给函数,即如果函数需要普通的char,则声明一个普通的char并获取其地址,依此类推。
C标准说“char”,“signed char”和“unsigned char”是不同的类型。 “char”必须与“signed char”或“unsigned char”具有相同的行为,由编译器开关确定,但不能互换使用它们。无论你是否使用-funsigned-char,你都应该编写完全相同的代码。
另一张海报使用演员表的建议并不好。所有这一切都是抑制警告,明确禁用警告会更清楚(例如,使用pragma,或者在makefile中全局关闭警告)。
强制转换不能解决代码问题,它只是阻止编译器指出它。这是一个稍微学术性的观点,但在非2的补码系统中,有符号的字符可能具有陷阱表示(它们是布局兼容的值0< = x< = CHAR_MAX而不是其他值)。所以代码可能会崩溃。
根据您提供的详细信息,实际上您最好的解决方案可能只是禁用警告,并且在这方面代码是不可移植的。
答案 3 :(得分:1)
最后我得到了答案:
-Wpointer-sign由-Wall和-pedantic隐含。为避免警告,请使用-Wno-pointer-sign