我遇到了一段代码,进行了以下初始化:
static const uint8_t s[] = {"Some string"};
Run Code Online (Sandbox Code Playgroud)
我希望它解释如下:右侧是一个char指针数组与单个元素匹配,指向字符串文字"Some string".而左边的部分是一个数组uint8_t
.然后我期望的行为是第一个s
接收字符串文字指针的截断值的元素,因此在下面的代码中引起意外行为,假设s
是一个字符串.
我做了以下测试代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,它似乎没有发生.不仅代码将正常工作,而且拆装表明,无论s1
与s2
被初始化为相同的方式对应的字符串.
这是gcc
具体的吗?C语法是否允许将单个字符串文字带入{}
并仍然将其解释为字符串文字?
nal*_*zok 17
引自N1570(C11的最终草案),6.7.9初始化(强调我的):
- 字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选地用大括号括起来.字符串文字的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素.
sun qingyao的答案正确地提到你可以为这样的初始化器添加额外的括号.值得一提的是,这不仅适用于数组:
int x = { 0 };
Run Code Online (Sandbox Code Playgroud)
即使初始化的元素不是数组也会编译.这要归功于以下条款:
6.7.9.11标量的初始值设定项应为单个表达式,可选择用大括号括起来.
但为什么会允许这样的事情呢?答案是,这使得使用单一语法初始化值成为可能:
T x = { 0 };
Run Code Online (Sandbox Code Playgroud)
适用于任何T
零和初始化所有内容(对于结构,每个成员,对于数组,每个元素,对于标量类型,只是初始化值).