C++中字符串文字的数据类型是什么?

Gab*_*是好人 16 c++ string type-conversion

有人质疑C++中字符串文字的数据类型.

很多人都引用了这个标准:

窄字符串文字的类型为"n const char数组",其中n是下面定义的字符串大小,并且具有静态存储持续时间(3.7)

我在main函数中写了以下语句:

  char cstring[]= "hellohellohellohellohellohello";
Run Code Online (Sandbox Code Playgroud)

但我找不到任何字符串文字作为静态数据存储在程序集中.事实上,程序集显示字符串被分解并直接"存储"在指令中.

    movl    $1819043176, -48(%rbp)
    movl    $1818585199, -44(%rbp)
    movl    $1701343084, -40(%rbp)
    movl    $1752132716, -36(%rbp)
    movl    $1869376613, -32(%rbp)
    movl    $1819043176, -28(%rbp)
    movl    $1818585199, -24(%rbp)
    movw    $28524, -20(%rbp)
    movb    $0, -18(%rbp)
Run Code Online (Sandbox Code Playgroud)

虽然全局范围中的类似语句因此将字符串存储为静态数据.

char cstring1[] = "hellohellohellohellohellohello";
Run Code Online (Sandbox Code Playgroud)

大会

cstring1:
    .string "hellohellohellohellohellohello"
Run Code Online (Sandbox Code Playgroud)

以上示例可在此处在线获取.

所以这似乎不符合引用的标准.也许这里引用的内容有一些例外情况?

Ste*_*sop 20

它符合"as-if"规则下的标准.

由于字符串文字的唯一用途是初始化cstring,因此不需要任何对象表示.编译器已经取消了它,有利于cstring通过具有相同结果的替代方法进行初始化,但编译器决定在某些方面(速度或代码大小)更好.


Ben*_*igt 10

表达式有类型.字符串文字如果用作表达式,则具有类型. 你的不是.

请考虑以下代码:

#include <stdio.h>

#define STR "HelloHelloHello"

char global[] = STR;

int main(void)
{
    char local[] = STR;
    puts(STR);
}
Run Code Online (Sandbox Code Playgroud)

此程序中有三个字符串文字使用相同的标记形成,但它们的处理方式不同.

第一个是初始化器global,是具有静态生命周期的对象的静态初始化的一部分.根据3.6.2节,静态初始化不必在运行时进行; 编译器可以安排在二进制映像中预先格式化结果,以便进程以已经存在的数据开始执行,并且在此处已经完成.local[]只要在全局变量动态初始化开始之前执行它,就像以下一样初始化这个对象也是合法的.

第二个,初始化器local,是一个字符串文字,但它不是一个真正的表达式.它是根据8.5.2的特殊规则处理的,该规则规定字符串文字中的字符独立用于初始化数组元素; 字符串文字不用作单位.此对象具有动态初始化,从而导致在运行时加载值.

第三个是puts()调用的参数,实际上确实使用了字符串文字作为表达式,并且它将具有类型const char[N],它会const char*为调用而衰减.如果你真的想学习用于处理字符串文字的运行时类型的目标代码,你应该在表达式中使用文字,就像这个函数调用一样.

  • @SteveJessop:是的,确实如此.在C++ 11标准的8.5节中查看*初始化程序*的语法.*initializer* - >*brace-or-equal-initializer* - >*`=`initializer-clause*,*initializer-clause* - >*assignment-expression*.在`char cstring1 [] ="hellohellohellohellohellohello";`中,字符串文字是*赋值表达式*.我不知道任何字符串文字可以出现的上下文,它不是某种表达式 - 无论它是如何使用的.我可以将`42;`写成一个语句,并且不使用表达式`42` - 但它仍然是一个带有类型的表达式. (2认同)
  • 显然我在这里遗漏了一些东西.正如你所说,语法*initializer-clause* - >*assignment-expression*已经在该位置允许*string-literal*.因此,*string-literal*在该上下文中是*assignment-expression*.该表达式的值和类型可能相关也可能不相关,具体取决于它的使用方式 - 但它仍然是一个表达式,它仍然具有类型`const char [N]`.为什么字符串文字由于其上下文而没有类型?在语句`42;`中,常量`42`不是`int`类型的? (2认同)