C语言 带花括号的字符串初始化器

pdkcd3nj  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(61)

我遇到了一段代码,它进行了以下初始化:

static const uint8_t s[] = {"Some string"};

字符串
我希望它被解释如下:右边是匹配一个字符指针数组,其中单个元素指向字符串字面量“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;
}


令我惊讶的是,它似乎没有发生。不仅代码将正确工作,而且反汇编显示s1s2都以相同的方式初始化为相应的字符串。
这是gcc特定的东西吗?C语法允许将单个字符串字面量带入{}并仍将其解释为字符串字面量吗?

u5i3ibmn

u5i3ibmn1#

引自N1570(C11的最终草案),6.7.9(强调矿):
1.字符类型的数组可以由字符串字面量或UTF-8字符串字面量初始化,可选地用大括号括起来。字符串字面量的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。

x8diyxa7

x8diyxa72#

孙庆耀的回答正确地提到,你可以给这样的初始化器添加额外的大括号。值得一提的是,这不仅适用于数组:

int x = { 0 };

字符串
compiles,即使被初始化的元素不是数组。这要归功于以下子句:
6.7.9.11标量的初始化器必须是一个表达式,可以用大括号括起来。
但是为什么会允许这样的事情呢?答案是,这使得用单一语法初始化值成为可能:

T x = { 0 };


适用于任何T和零重命名一切(对于结构,每个成员,对于数组,每个元素,对于标量类型,只是重命名值)。

相关问题