C++ 能否在堆栈上分配常量静态字符串?

C++ 能否在堆栈上分配常量静态字符串?,c++,c,memory,C++,C,Memory,一致性编译器能否决定在堆栈上分配“abcdef”?也就是说,标准中的什么强制编译器在.data部分分配它 标准中的什么强制编译器在.data上分配它 部门 没什么。但它肯定不在堆栈上,因为指向字符串文字的指针永远不能失效(因为文字具有静态存储持续时间1),堆栈上的值在某个点被其他帧覆盖。而具有静态存储持续时间的对象通常位于专用于该存储时间的部分--.data部分 根据“似乎”规则,如果程序的可观察行为没有改变,他可以将其放在堆栈上;但是,这是不太可能发生的,因为这对程序的性能没有任何好处(而且没

一致性编译器能否决定在堆栈上分配
“abcdef”
?也就是说,标准中的什么强制编译器在
.data
部分分配它

标准中的什么强制编译器在.data上分配它 部门

没什么。但它肯定不在堆栈上,因为指向字符串文字的指针永远不能失效(因为文字具有静态存储持续时间1),堆栈上的值在某个点被其他帧覆盖。而具有静态存储持续时间的对象通常位于专用于该存储时间的部分--
.data
部分

根据“似乎”规则,如果程序的可观察行为没有改变,他可以将其放在堆栈上;但是,这是不太可能发生的,因为这对程序的性能没有任何好处(而且没有意义的相关编译器尚未编写)


1) [lex.string]/8:

还引用了普通字符串文字和UTF-8字符串文字 将其转换为窄字符串文字。窄字符串文字的类型为“array” n
const char
”,其中n是如下定义的字符串大小, 并且具有静态存储持续时间(3.7)

参考N1570(C11草案)
6.4.5/6
String-literals(今后的重点):

在翻译阶段7中,将值为零的字节或代码附加到每个多字节 由一个或多个字符串文本生成的字符序列。78) 然后使用多字节字符序列初始化数组 静态存储持续时间和长度刚好足以容纳 序列对于字符串文字,数组元素的类型为
char
,并使用多字节中的单个字节进行初始化 字符序列

这意味着字符串文字具有整个程序执行的生命周期,如
6.2.4/3
对象的存储持续时间:

一种对象,其标识符是在没有存储类的情况下声明的 说明符
\u Thread\u local
,具有外部或内部链接,或与存储类说明符
static
具有静态存储持续时间。它的 生存期是程序及其存储值的整个执行过程 仅在程序启动之前初始化一次

由于其性质,编译器不太可能将它们放在堆栈上(提示:函数调用之间的保留)


注意,C标准并没有明确禁止在堆栈上放置字符串文本。事实上,它甚至没有定义堆栈或
.data
节这样的术语。这是由编译器决定的,无论是什么数据布局,都符合标准。

< P>从C++规范中,2.2.5/8为字符串文字; 普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“array of n
const char
”,其中n是下面定义的字符串大小,并且具有静态存储持续时间(3.7)

还值得一提的是,静态存储持续时间适用于所有字符串文本;因此,
L”“
u”“
u”“
等;§2.14.5/10-12

反过来,对于静态存储持续时间§3.7.1/1

所有没有动态存储持续时间、没有线程存储持续时间和非本地的变量都有静态存储持续时间。这些实体的存储应在项目期间持续(3.6.2、3.6.3)

因此,您的字符串
“abcdef”
将在程序期间存在。编译器可以选择存储它的位置(这可能是一个系统约束),但它必须保持有效

对于C语言规范(C11草案n1570),字符串文字§6.4.5/6

在翻译阶段7中,将值为零的字节或代码附加到由字符串文字产生的每个多字节字符序列中。然后使用多字节字符序列初始化静态存储持续时间和长度刚好足以包含该序列的数组。对于字符串文字,数组元素的类型为
char
,并使用多字节字符序列的各个字节进行初始化

以及静态存储持续时间§6.2.4/3

如果对象的标识符是在没有存储类说明符
\u Thread\u local
的情况下声明的,并且具有外部或内部链接,或者具有存储类说明符static,则该对象具有静态存储持续时间其生命周期是程序的整个执行过程,其存储值仅在程序启动前初始化一次


同样的定位原理也适用(很可能是系统约束),但必须在课程期间保持有效。

之前的答案已经引用了标准,因此我将采用逻辑方法

每次调用函数时,您都可以将此文本字符串从RO数据部分复制到堆栈中:

const char * foo()
{
    return "abcdef";
}

int main()
{
    printf("%s", foo());
}
但是这个函数返回一个指针

您肯定不希望该指针在堆栈中包含地址


因此,在堆栈上首先分配文本字符串是没有意义的。

所有静态持续时间必须保持分配状态,直到程序退出;这类东西可能位于堆栈上,但前提是它们在执行任何用户代码之前被分配。这种设计是不寻常的,但在插件体系结构中可能是有利的,例如,希望多个线程同时运行一个插件,并使每个线程的实例完全独立运行
const char* foo()
{
    const char str[] = "abcdef";
    return str;
}