字符串字面值的编译

4
为什么两个用空格、制表符或 "\n" 分隔的字符串字面量可以编译而不出错?
int main()
{
   char * a = "aaaa"  "bbbb";
} 

"aaaa"是一个字符* "bbbb"是一个字符*

没有特定的连接规则来处理两个字符串字面值。很明显,以下代码在编译时会出错:

#include <iostream>
int main()
{
   char * a = "aaaa";
   char * b = "bbbb";
   std::cout << a b;
}

这种连接方式在所有编译器中都常见吗?"aaaa"的空终止在哪里?"aaaabbbb"是一块连续的内存吗?


5
这些是字符数组,而非指针。 - M.M
5个回答

9
如果你看到例如这个翻译阶段参考在第6阶段中它会做以下事情:

相邻的字符串文字将被连接。

这正是此处发生的情况。您有两个相邻的字符串文字,它们被连接成一个单一的字符串文字。
这是标准行为。
它仅适用于字符串文字,而不适用于两个指针变量,正如您所注意到的。

5
在这个语句中
char * a = "aaaa"  "bbbb";

编译器在语法分析之前的某个步骤中,将相邻的字符串文字视为一个文字。

因此,对于编译器来说,上述语句等同于

char * a = "aaaabbbb";

编译器仅存储一个字符串字面量"aaaabbbb"


4

根据C(和C ++)标准的规定,相邻的字符串字面量将被连接。但是对于相邻的标识符(即变量ab),不存在这样的规则。

引用C ++14(N3797草案),§ 2.14.5:

在翻译阶段6(2.2)中,相邻的字符串字面量被连接。如果两个字符串字面量具有相同的编码前缀,则生成的串联字符串字面量具有该编码前缀。如果一个字符串字面量没有编码前缀,则它被视为另一个操作数的具有相同编码前缀的字符串字面量。如果一个UTF-8字符串字面量令牌与一个宽字符串字面量令牌相邻,则程序是非法的。任何其他连接都具有条件支持和实现定义的行为。


3
在 C 和 C++ 中,相邻的字符串字面量会被编译为一个单独的字符串字面量。例如这个例子:
"Some text..." "and more text"

等同于:

"Some text...and more text"

由于历史原因:
最初的C语言是在1969-1972年设计的,当时计算机仍然以80列打孔卡为主导。它的设计者使用了80列设备,例如ASR-33 Teletype。这些设备不会自动换行,因此有一个真正的动机将源代码保持在80列内。Fortran和Cobol在最终转向自由格式之前采用了明确的续行机制。
Dennis Ritchie(我认为)意识到语法中没有歧义,长ASCII字符串可以通过编译器简单地连接相邻的文字字符串来适应80列,这是一种非常聪明的想法。无数的C程序员对这个小特性感激不尽。
一旦有了这个功能,为什么会被删除呢?它不会引起任何麻烦,并且经常很方便。我希望更多的语言也有这样的功能。现代趋势是使用三重引号或其他符号扩展字符串,但是C语言中这个功能的简单性从未被超越过。 类似的问题在这里

1
你从哪里找到那个引用的? - anatolyg
@anatolyg 添加了引用 - BiagioF

2
相邻的字符串字面量会在第六阶段(预处理器之后)进行连接。也就是说,"Hello," " world!"将会得到(单个)字符串"Hello, world!"。如果这两个字符串有相同的编码前缀(或者都没有前缀),则结果字符串将具有相同的编码前缀(或没有前缀)。
source

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接