我很确定Visual C ++ 2015在这里有一个错误,但我并不完全确定。
代码:
// 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;
}
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,“π”, ,则两个编译器的行为都没有变化,所以这似乎并不重要。
答案 0 :(得分:1)
来自 [lex.string] :
- 在翻译阶段6中,连接相邻的字符串文字。如果两个字符串文字具有相同的encoding-prefix,则生成的连接字符串文字具有该encoding-prefix。 如果一个字符串文字没有编码前缀,则将其视为与另一个操作数相同的编码前缀的字符串文字。如果UTF-8字符串文字标记与宽字符串文字相邻令牌,该程序是不正确的。任何其他 通过实现定义的行为有条件地支持连接。 [注意:此连接是一种解释,而不是转换。因为解释发生在翻译阶段6(之后 来自文字的每个字符都被翻译成来自适当字符集的值),字符串文字的初始原始性对连接的解释或良好形成没有影响。 -结束 注意]表8列出了一些有效连接的例子。
醇>
所以这里没有UB,但翻译的第5阶段可能已经改变了某些字符的值:
- 字符文字中的每个源字符集成员或字符串文字,以及每个转义序列和通用字符名称在字符文字或非原始字符串文字中,如果没有相应的成员,则转换为执行字符集的相应成员,将其转换为除null之外的实现定义成员 (宽)字符。
醇>