在C11中,字符串文字为char [],unsigned char [],char *和unsigned char *

时间:2017-12-21 11:10:10

标签: c string-literals unsigned-char

通常字符串文字是const char []的类型。但当我把它视为其他类型时,我得到了奇怪的结果。

unsigned char *a = "\355\1\23";

使用此编译器抛出警告说“初始化中的指针目标在签名方面不同”,这是非常合理的,因为可以丢弃符号信息。

但是跟随

unsigned char b[] = "\355\1\23";

根本没有警告。我认为应该有一个警告,出于同样的原因。怎么可能呢?

仅供参考,我使用GCC版本4.8.4。

2 个答案:

答案 0 :(得分:1)

C中的字符串文字类型为char[],它会衰减到char*。请注意,C与C ++不同,它们的类型为const char[]

在第一个示例中,您尝试将char*分配给unsigned char*。这些是不兼容的类型,因此您将获得编译器诊断消息。

在第二个例子中,以下适用,C11 6.7.9 / 14:

  

字符类型数组可以用字符串文字或UTF-8字符串初始化   文字,可选择括在括号中。字符串文字的连续字节(包括   如果有空间或数组的大小未知,则终止空字符)初始化   数组的元素。

意思是代码与此相同:

unsigned char b[] = 
{ 
  '\355',
  '\1',
  '\23',
  '\0'
};

这也可能会产生警告,但它是有效的代码。对于不同整数类型之间的赋值 1 ,C具有松散类型安全性,但在指针类型之间进行赋值时要严格得多。

出于同样的原因,我们可以写unsigned int x=1;而不是unsigned int x=1u;

作为旁注,我不知道你希望用值为355的八进制转义序列实现什么。也许你打算写"\35" "5\1\23"

1 初始化的类型规则与赋值相同。 6.5.16.1"简单分配"适用。

答案 1 :(得分:1)

第一个是指针的初始化,指针的目标类型必须在签名上达成一致。

第二个是数组的初始化。使用字符串文字初始化的特殊规则使得文字的每个字符的用于初始化数组的各个元素。

除了你陈述之外,BTW,字符串文字在C中不是const限定的。你没有权利修改它们,但这并没有反映在类型中。