我遇到了一段代码,它进行了以下初始化:
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;
}
型
令我惊讶的是,它似乎没有发生。不仅代码将正确工作,而且反汇编显示s1
和s2
都以相同的方式初始化为相应的字符串。
这是gcc
特定的东西吗?C语法允许将单个字符串字面量带入{}
并仍将其解释为字符串字面量吗?
2条答案
按热度按时间u5i3ibmn1#
引自N1570(C11的最终草案),6.7.9(强调矿):
1.字符类型的数组可以由字符串字面量或UTF-8字符串字面量初始化,可选地用大括号括起来。字符串字面量的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。
x8diyxa72#
孙庆耀的回答正确地提到,你可以给这样的初始化器添加额外的大括号。值得一提的是,这不仅适用于数组:
字符串
compiles,即使被初始化的元素不是数组。这要归功于以下子句:
6.7.9.11标量的初始化器必须是一个表达式,可以用大括号括起来。
但是为什么会允许这样的事情呢?答案是,这使得用单一语法初始化值成为可能:
型
适用于任何
T
和零重命名一切(对于结构,每个成员,对于数组,每个元素,对于标量类型,只是重命名值)。