Rei*_*ica 15 c++ string-literals language-lawyer
我知道char用字符串文字初始化数组是完全可能的:
char arr[] = "foo";
Run Code Online (Sandbox Code Playgroud)
C++ 11 8.5.2/1这样说:
甲
char阵列(是否平原char,signed char或unsigned char),char16_t阵列,char32_t阵列或wchar_t阵列可通过一个窄字符文字,初始化char16_t字符串文字,char32_t字符串文字或宽字符串文字,分别或通过适当类型的字符串文字括在括号内.字符串文字值的连续字符初始化数组的元素....
但是,你可以在条件表达式中使用两个字符串文字吗?例如这样:
char arr[] = MY_BOOLEAN_MACRO() ? "foo" : "bar";
Run Code Online (Sandbox Code Playgroud)
(MY_BOOLEAN_MACRO()扩展为a 1或0).
C++ 11 5.16(条件运算符)的相关部分如下:
1 ...第一个表达式在上下文中转换为
bool(第4条).它被评估,如果是true,则条件表达式的结果是第二个表达式的值,否则是第三个表达式的值....4如果第二个和第三个操作数是相同值类别的glvalues并且具有相同的类型,则结果属于该类型和值类别,如果第二个或第三个操作数是位字段,则它是位字段,或者如果两者都是位字段.
请注意,文字的长度相同,因此它们都是类型的左值const char[4].
GCC one ideone接受该构造.但是从阅读标准来看,我根本不确定它是否合法.有没有人有更好的洞察力?
Sha*_*our 10
另一方面clang,不接受这样的代码(看到它直播),我相信这clang是正确的(MSVC也拒绝这个代码).
甲文字串是通过在段语法定义2.14.5:
string-literal:
encoding-prefixopt" s-char-sequenceopt"
encoding-prefixoptR raw-string
Run Code Online (Sandbox Code Playgroud)
本节的第一段说(强调我的):
字符串文字是由双引号括起的字符序列(如2.14.3中所定义) ,可选地以R,u8,u8R,u,uR,U,UR,L或LR为前缀,如"......"中所示. ,R"(...)",u8"......",u8R" (...) ",u"...",uR" 〜(...)〜",U"......" ,UR"zzz(...)zzz",L"......"或LR"(...)"
并进一步说明了一个狭窄的字符串文字的类型是:
"n const char数组",
以及:
有静态存储时间
但是一个"n const char数组",静态存储持续时间不是字符串文字,因为它不符合语法,也不适合段落1.
gcc如果我们使用非常量表达式,我们可以使它失败(请参见实时):
bool x = true ;
char arr[] = x ? "foo" : "bar";
Run Code Online (Sandbox Code Playgroud)
这意味着它可能是一个扩展,但它不符合要求,因为它不会在严格的一致性模式下产生警告,即使用-std=c++11 -pedantic.来自1.4 [intro.compliance]部分:
[...]根据本国际标准,需要实施来诊断使用此类扩展的程序.但是,这样做之后,他们就可以编译和执行这样的程序.