字符串文字串联的正确行为(C++ 11翻译阶段6)

Che*_*Alf 6 c++ g++ visual-c++

我很确定Visual C++ 2015在这里有一个bug,但我并不完全确定.

码:

// Encoding: UTF-8 with BOM (required by Visual C++).
#include <stdlib.h>

auto main()
    -> int
{
    auto const s = L""
        " is not in the Unicode BMP!";
    return s[0] > 256? EXIT_SUCCESS : EXIT_FAILURE;
}
Run Code Online (Sandbox Code Playgroud)

使用g ++的结果:

[H:\scratchpad\simple_text_io]
> g++ --version | find "++"
g++ (i686-win32-dwarf-rev1, Built by MinGW-W64 project) 6.2.0

[H:\scratchpad\simple_text_io]
> g++ compiler_bug_demo.cpp

[H:\scratchpad\simple_text_io]
> run a
Process exit code = 0.

[H:\scratchpad\simple_text_io]
> _

Visual C++的结果:

[H:\scratchpad\simple_text_io]
> cl /nologo- 2>&1 | find "++"
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23026 for x86

[H:\scratchpad\simple_text_io]
> cl compiler_bug_demo.cpp /Feb
compiler_bug_demo.cpp
compiler_bug_demo.cpp(8): warning C4566: character represented by universal-character-name '\U00010437' cannot be represented in the current code page (1252)

[H:\scratchpad\simple_text_io]
> run b
Process exit code = 1.

[H:\scratchpad\simple_text_io]
> _

是否涉及任何UB,如果没有,哪个编译器行为正确?

附录:

如果在BMP中使用小写希腊PI,"π",两个编译器的行为都不会改变,因此这似乎并不重要.

Rev*_*lot 2

来自[lex.string]

\n\n
\n
    \n
  1. 在翻译阶段 6,相邻的字符串文字被连接起来。如果两个字符串文字具有相同的编码前缀,则生成的串联字符串文字具有该编码前缀。如果一个字符串文字没有编码前缀,则将其视为与另一操作数具有相同编码前缀的字符串文字。如果 UTF-8 字符串文字标记与宽字符串文字标记相邻,则程序格式错误。任何其他连接都通过实现定义的行为有条件地支持。[ 注意:此连接是一种解释,而不是转换。因为解释发生在翻译阶段 6(在将文字中的每个字符翻译为相应字符集中的值之后),所以字符串文字 \xe2\x80\x99 的初始原始性对解释或良好没有影响。连接的形成性。\xe2\x80\x94end\n 注意] 表 8 提供了一些有效串联的示例。
  2. \n
\n
\n\n

所以这里没有 UB,但是翻译的第 5 阶段可能已经更改了某些字符的值:

\n\n
\n
    \n
  1. 字符文字或字符串文字中的每个源字符集成员,以及字符文字或非原始字符串文字中的每个转义序列和通用字符名称,都将转换为执行字符集的相应成员,如果没有相应的成员,它被转换为除空(宽)字符之外的实现定义的成员。
  2. \n
\n
\n