我遇到了一段代码,进行了以下初始化:
static const uint8_t s[] = {"Some string"};
我希望它被解释如下:右侧是一个char指针数组与单个元素匹配,它指向一个字符串文字"一些字符串"。左边部分是uint8_t
的数组。然后我期望的行为是s
的第一个元素接收指向字符串文字的指针的一些截断值,因此在下面的代码中导致意外行为,假设s
是一个字符串。 / p>
我已经制作了以下测试代码:
#include <stdint.h>
#include <stdio.h>
static const uint8_t s1[] = "String1";
static const uint8_t s2[] = { "String2" };
int main(void){
printf("%p, %p\n", s1, s2);
printf("%s, %s\n", s1, s2);
return 0;
}
令我惊讶的是,它似乎没有发生。不仅代码可以正常工作,而且反汇编显示s1
和s2
都以相同的方式初始化为相应的字符串。
这是gcc
具体的吗? C语法是否允许将单个字符串文字转换为{}
并仍然将其解释为字符串文字?
答案 0 :(得分:16)
引自N1570(C11的最终草案),6.7.9初始化(强调我的):
- 字符类型的数组可以由字符串初始化 文字或UTF-8字符串文字,可选择用大括号括起来。 字符串文字的连续字节(包括终止空值) 字符,如果有空间或数组的大小未知) 初始化数组的元素。
醇>
答案 1 :(得分:8)
sun qingyao的答案正确地提到你可以为这样的初始化器添加额外的括号。值得一提的是,这不仅适用于数组:
int x = { 0 };
compiles即使初始化的元素不是数组。这要归功于以下条款:
6.7.9.11 标量的初始值设定项应为单个表达式,可选择用括号括起来。
但为什么会允许这样的事情呢?答案是,这可以使用单一语法初始化值:
T x = { 0 };
适用于任何T
并对所有内容进行零初始化(对于结构,每个成员,数组,每个元素,标量类型,只是初始化值)。