警告:由括号字符串文字初始化的数组'alphabet'

时间:2014-02-24 10:35:37

标签: c++ arrays string c++11 initialization

在模板化函数中,我目前有以下一行:

static const unsigned char alphabet[17] = 
(Uppercase) ? ("0123456789ABCDEF") : ("0123456789abcdef");

其中Uppercase是模板参数。 -pedantic gcc告诉我:

warning: array 'alphabet' initialized by parenthesized string literal 
'("0123456789abcdef")'

如何摆脱该消息(我希望alphabet在堆栈中)?

2 个答案:

答案 0 :(得分:3)

使代码明确有效的最简单方法是使用对数组的引用:

static const char (&alphabet)[17] = 
    (Uppercase) ? ("0123456789ABCDEF") : ("0123456789abcdef");

这并不依赖于允许字符串文字用于数组初始化的特殊异常。正如neverhoodboy所指出的,它确实需要您处理char数组,而不是unsigned char数组。

如果您真的需要使用额外辅助变量的unsigned char数组,您仍然可以使用它:

static const unsigned char uppercase[17] = "0123456789ABCDEF";
static const unsigned char lowercase[17] = "0123456789abcdef";
static const unsigned char (&alphabet)[17] =
    (Uppercase) ? uppercase : lowercase;

注意:如果在编译时知道Uppercase(您说它是模板参数,那么它应该是),您也可以添加constexpr关键字。

答案 1 :(得分:1)

("abc")是“4个const chars数组”类型的表达式,是一个左值。但是("abc")不是字符串文字。字符串文字是标记,即看起来特别像“......”的标记。 char数组可以由字符串文字初始化为特殊语法,但不能是const字符类型数组的任意表达式。因此,使用("abc")作为char数组的初始化程序是非法的。即使你删除括号,你的情况下的初始化程序仍然是一个表达式(一个条件表达式,虽然它的类型是const字符数组,它是左值),因此不能用于初始化一个char数组。

因此,我认为在堆栈中使用alphabet并根据单个声明中的条件初始化为其中一个字符串文字是合法的方法。另一个答案中提到的参考方法初始化很好,但不满足您的堆栈存储要求 编辑:另一个答案中的第二种方法非常适合作为帮助者的两个额外声明。

摘自标准:

对于带括号的表达式:

  

带括号的表达式是一个主表达式,其类型和值与所附表达式的类型和值相同。括号的存在不会影响表达式是否为左值。括号表达式可以在与可以使用封闭表达式的语境完全相同的上下文中使用,并且具有相同的含义,除非另有说明。

对于条件表达式:

  

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

对于字符数组初始化:

  

char数组(无论是普通字符,有符号字符还是无符号字符),char16_t数组,char32_t数组或wchar_t数组可以通过窄字符文字,char16_t字符串文字,char32_t字符串文字或宽字符串文字来初始化,分别,或由括在括号中的适当类型的字符串文字。字符串文字值的连续字符初始化数组的元素。