当前缀字符串与非前缀字符串相邻时,字符串文字连接失败?

Posted

技术标签:

【中文标题】当前缀字符串与非前缀字符串相邻时,字符串文字连接失败?【英文标题】:String literal concatenation fails when prefixed string is adjacent to non-prefixed string? 【发布时间】:2013-12-19 16:51:03 【问题描述】:

在我认为符合 C++11 的 MSVS2013 中,编译器不喜欢以下内容:

LPCTSTR str = _T("boo " "hoo");

翻译为:

wchar_t const * str = L"boo " "hoo";

根据cppreference.com(我知道这不是确定的,但这是我目前唯一的参考资料):

并排放置的字符串文字会在编译期间连接。即“你好”、“世界!”产生(单个)字符串“Hello,world!”。 如果两个字符串具有相同的编码前缀(或两者都没有),则生成的字符串将具有相同的编码前缀(或没有前缀)。 如果其中一个字符串有编码前缀而另一个没有,则认为没有的字符串与另一个字符串具有相同的编码前缀。强> 如果 UTF-8 字符串字面量和宽字符串字面量并排,则程序格式错误。 实施可能支持也可能不支持任何其他编码前缀组合。这种连接的结果是实现定义的。

重点是我自己的。

谁能确认这是否符合 cppreference 所指出的标准?

编辑

不喜欢,我的意思是我收到以下错误:

error C2308: concatenating mismatched strings

【问题讨论】:

FWIW,该错误的 MSDN documentation 确实表明您不允许连接宽和非宽字符串文字。所以这看起来像是一个尚未实现的 C++11 功能。您应该在 Microsoft Connect 上提交错误报告。 MSVS2013 声称 是否(完全)支持 C++2011?无论如何都要报告它,但不清楚它是否真的是一个 bug 本身。 @KeithThompson,据我所知,他们仍在向 C++11 和 C++14 发展,尽管没有任何信息表明这是否在列表中去做。 【参考方案1】:

2003 ISO C++ 标准第 2.13.4p3 节说:

在翻译阶段 6 (2.1) 中,相邻的窄字符串文字是 连接的和相邻的宽字符串文字是连接的。如果一个 窄字符串文字标记与宽字符串文字相邻 令牌,行为未定义。连接字符串中的字符 保持不同。

2011 年标准第 2.14.5p13 节说:

在翻译阶段 6 (2.2) 中,相邻的字符串字面量是 串联。如果两个字符串文字具有相同的 encoding-prefix, 生成的连接字符串文字具有 encoding-prefix。 如果一个字符串文字没有 encoding-prefix,则将其视为 与另一个操作数具有相同编码前缀的字符串文字。如果一个 UTF-8 字符串文字标记与宽字符串文字标记相邻, 该程序格式不正确。任何其他连接都是有条件的 支持实现定义的行为。

因此,序列L"boo " "hoo" 在 C2003 中具有未定义的行为,但定义明确,等效于 C2011 中的 L"boohoo"

从您提供的信息中我无法判断 MSVS2013 是否符合 C++11。您说它“不喜欢”该构造,但如果不喜欢被表达为非致命警告并且语义符合 2011 年标准中的规定,那么它可能符合要求。

您能否更新问题以显示诊断消息?

【讨论】:

两个答案都很好。我只给了你,因为你在发帖时快了一分钟。 :) @Adrian:我提到这是 2003 年标准下未定义的行为。【参考方案2】:

来自 N3797,§2.14.5/13 [lex.string]

在翻译阶段 6 (2.2) 中,相邻的字符串文字是 串联。如果两个字符串文字具有相同的编码前缀, 生成的连接字符串文字具有该编码前缀。如果 一个字符串文字没有编码前缀,它被视为字符串 与另一个操作数具有相同编码前缀的文字。

下面的表格甚至列出了一个与您展示的相同的示例

// Source         Means
L"a" "b"          L"ab"

所以我想说你的代码格式正确,这是一个 VisualStudio 错误。

【讨论】:

以上是关于当前缀字符串与非前缀字符串相邻时,字符串文字连接失败?的主要内容,如果未能解决你的问题,请参考以下文章

可以在 Python 中制作自定义字符串文字前缀吗?

连接相邻字符串文字时的 Python 运算符优先级

当前缀设置为超过 1 个字符时,Discord Bot 不会回复

在检查比特币块时,为什么一旦找到正确的随机数就会得到一个前导零的前缀?

WinAPI 中的 sz 和 pwsz 前缀

当用于 Blob 存储的 Azure REST API 使用具有前缀或标记的查询字符串时获取 403