是否可以用条件选择的字符串字面量初始化字符数组? [英] Is it possible to initialise a character array with a conditionally selected string literal?

查看:228
本文介绍了是否可以用条件选择的字符串字面量初始化字符数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道可以使用字符串字面量初始化一个 char 数组:

  char arr [] =foo; 

C ++ 11 8.5.2 / 1说:


A char 数组(无论是否 char signed char unsigned char ), char16_t 数组, char32_t 数组或
wchar_t 数组可以通过一个窄字符文字初始化, char16_t 字符串字面量, char32_t string
立即数或宽字符串字面值,或用大括号括起来的适当类型的字符串文字。
字符串文字的值的连续字符初始化数组的元素。 ...


但是,你可以在条件表达式中使用例如像这样:

  char arr [] = MY_BOOLEAN_MACRO()? foo:bar; 

(其中 MY_BOOLEAN_MACRO() 1 0 )。



C ++ 11 5.16(条件运算符)如下:


1 ...第一个表达式上下文转换为 bool (第4条)。
它被评估,如果它是 true ,条件表达式的结果是第二个表达式的值
否则第三个表达式的值。 ...



4如果第二个和第三个操作数是相同值类别的glvalues并且具有相同的类型,结果
是该类型和值类别,如果第二或第三操作数是位字段,或者如果
都是位字段,则它是位字段。


请注意,文字长度相同,因此它们都是类型 const char [4] 的左值。



GCC一个ideone 接受此构造。但是从阅读标准,我只是不知道它是否合法。

解决方案

另一方面, clang 不接受此类代码( 查看实时 ),我相信 clang 是正确的( MSVC也拒绝此代码 )。



字符串文字 2.14.5 部分的语法定义:

  string-literal:
encoding-prefixopts-char-sequenceopt
encoding-prefixoptR raw- string

,第一段说明(重点我


字符串字符是字符序列(如2.14.3中定义)
< strong用双引号包围,可选择以R,u8,u8R,u,uR,
U,UR,L或LR为前缀, 。),u8...,u8R(...)
u...,uR em ...,U...,URzzz(...)zzz,L...或LR(...),
分别

b $ b

,并进一步指出,一个窄字符串文字的类型是:


n const char数组,


以及:


有静态存储持续时间


,因为它不适合语法,也不适合段落 1 。 p>

如果我们使用非常量表达式( gcc http://melpon.org/wandbox/permlink/gEV3ImIU5KBYa5eerel =nofollow>查看活动 ):

  bool x = true; 
char arr [] = x? foo:bar;

这意味着它可能是一个扩展,但它是不符合,因为它不产生警告在严格符合模式(即使用 -std = c + +11 -pedantic 。从 1.4 [intro.compliance] 部分:


[...]需要使用实现来诊断使用这种
扩展的程序,这些扩展根据此国际
标准是不合格的。但是,这样做后,他们可以编译并执行这样的
程序。



I know it's perfectly possible to initialise a char array with a string literal:

char arr[] = "foo";

C++11 8.5.2/1 says so:

A char array (whether plain char, signed char, or unsigned char), char16_t array, char32_t array, or wchar_t array can be initialized by a narrow character literal, char16_t string literal, char32_t string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces. Successive characters of the value of the string literal initialize the elements of the array. ...

However, can you do the same with two string literals in a conditional expression? For example like this:

char arr[] = MY_BOOLEAN_MACRO() ? "foo" : "bar";

(Where MY_BOOLEAN_MACRO() expands to a 1 or 0).

The relevant parts of C++11 5.16 (Conditional operator) are as follows:

1 ... The first expression is contextually converted to bool (Clause 4). It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. ...

4 If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.

Notice that the literals are of the same length and thus they're both lvalues of type const char[4].

GCC one ideone accepts the construct. But from reading the standard, I am simply not sure whether it's legal or not. Does anyone have better insight?

解决方案

On the other hand clang does not accept such code (see it live) and I believe clang is correct on this (MSVC also rejects this code ).

A string literal is defined by the grammar in section 2.14.5:

string-literal:
    encoding-prefixopt" s-char-sequenceopt"
    encoding-prefixoptR raw-string

and the first paragraph from this section says (emphasis mine):

A string literal is a sequence of characters (as defined in 2.14.3) surrounded by double quotes, optionally prefixed by R, u8, u8R, u, uR, U, UR, L, or LR, as in "...", R"(...)", u8"...", u8R"(...)", u"...", uR"˜(...)˜", U"...", UR"zzz(...)zzz", L"...", or LR"(...)", respectively

and it further says that the type of a narrow string literal is:

"array of n const char",

as well as:

has static storage duration

but an "array of n const char", with static storage duration is not a string literal since it does not fit the grammar nor does it fit paragraph 1.

We can make this fail on gcc if we use a non-constant expression (see it live):

bool x = true ;
char arr[] = x ? "foo" : "bar";

which means it is probably an extension, but it is non-conforming since it does not produce a warning in strict conformance mode i.e. using -std=c++11 -pedantic. From section 1.4 [intro.compliance]:

[...]Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.

这篇关于是否可以用条件选择的字符串字面量初始化字符数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆