为什么 C 标准规定字符串文字应以初始移位状态开始和结束?

Why does the C standard state that string literals shall begin and end in the initial shift state?

ANSI X3.159-1989“C 语言编程”标准在“5.2.1.2 - 多字节字符”一章中指出:

For the source character set, the following shall hold:

  • A comment, string literal, character constant, or header name shall begin and end in the initial shift state.
  1. 是不是表示字符串字面量等应该以字符开始和结束,用初始移位状态的值表示,即单字节值?或者这是否意味着环境应该在处理某个字符串文字等之前和之后将其当前的移位状态重置为初始移位状态?

  2. 为什么会这样? - IE。设置初始移位状态的目的是什么,尤其是在字符串文字的末尾等?

Why does the C standard state that string literals shall begin and end in the initial shift state?

让我们首先看看“转换状态”到底是什么意思(或者按照规范得到的那样):

A multibyte character may have a state-dependent encoding, wherein each sequence of multibyte characters begins in an initial shift state and enters other implementation-defined shift states when specific multibyte characters are encountered in the sequence. While in the initial shift state, all single-byte characters retain their usual interpretation and do not alter the shift state. The interpretation for subsequent bytes in the sequence is a function of the current shift state.

要求字符串文字以初始移位状态开始和结束使字符串语义更简单且更可预测。如果您连接两个字符串,或者一个接一个地输出它们,您可以确信它们的并置不会改变后者的含义。如果第一个可以以不同于初始状态的转换状态终止,则无法保证。

所有这一切背后的内在假设是 language-level 语义不知道任何特定字符编码的细节。他们将所有字符串都视为字节的黑框,以空字符结尾。

  1. Does it mean that a string literal or etc. shall begin and end with a character, represented by a value of the initial shift state, i.e. a single-byte value? Or does it mean that the environment shall reset it's current shift state to the initial shift state before and after processing a certain string literal or etc?

都没有。使用 state-dependent 编码,当前移位状态是 运行 属性 对编码字符序列的解释。字符不一定直接编码移位状态,但编码方案提供了一种指定移位状态变化的方法。

细节可能因特定的编码方案而异,但编码的字符,无论是单字节还是多字节,通常并不固有地处于特定的移位状态。这种编码的全部意义在于,相同的子序列可能会根据移位状态而有不同的解释。因此,从初始移位状态开始是关于如何解释多字节字符序列的断言,并且仅通过暗示说明字符串文字必须包含的内容。

在初始移位状态结束,另一方面,对字符串内容的约束,etc。如果字符串文字的字节 etc,则 C 源文件格式错误。其中,解释为从初始移位状态开始,对一个或多个状态移位进行编码,使得字节序列末尾的移位状态不同于初始移位状态。这正是为了让实现不必关心编码问题,绝对不要求它执行任何类型的 shift-state 清理。

  1. Why so? - I.e. what is the purpose to set the initial shift state, especially at the end of a string literal or etc?

它简化了语言并提高了用 state-dependent 源编码编写的 C 源文件的可维护性。每个接受 user-defined 自由文本的单元都是模块化的——它具有相同的 well-defined 含义,无论周围的上下文如何,移动、复制或删除这些单元都不能改变其词法解释周围的标记。