为什么使用字符串字面值初始化无符号字符数组是可以的,但使用它来初始化无符号字符指针却不行?

8
我尝试使用gcc -Wall -pedantic-errors -std=c89编译以下代码:
int main(){
  unsigned char a[] = "foo";
  unsigned char *b= "foo";
  unsigned char *c= ( unsigned char *) "foo";
  return 0;
}

为什么第二个初始化会引发错误“pointer targets in initialization differ in signedness”,而其他两个声明是允许的?
看起来在第二种情况下,从char *到unsigned char *的隐式转换没有完成。

1
char*unsigned char* 没有 "隐式转换",这就是为什么第二个失败的原因。 - rici
对的,第一个也没有执行那个转换。它是逐个复制字符数组元素。 - Nemo
1个回答

5
从技术上讲,因为标准明确允许使用字符串字面值(6.7.9p14)初始化任何字符类型的数组:

字符类型的数组可以用字符字符串字面值或UTF-8字符串字面值进行初始化,可选地用花括号括起来。字符串字面值的连续字节(包括终止空字符,如果有空间或数组大小未知)将初始化数组的元素。

而对于大多数指针转换,标准要求使用显式转换(6.5.4p3):

涉及指针的转换,除非符合6.5.16.1的限制,否则必须通过显式转换来指定。

直观地说,因为你可以这样做:
unsigned char a0 = 'f', a1 = 'o', a2 = 'o';

换句话说,因为您可以使用不同的整数类型初始化整数类型而无需显式转换。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接