哪些具有char数组的新表达式格式正确? [英] Which of these new expressions with char arrays are well-formed?

查看:124
本文介绍了哪些具有char数组的新表达式格式正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于以下程序

  int main()
{
new char [4] { text}; //#1
new char [5] {" text"}; //#2
new char [] { text}; //#3
}

clang给出#1 表示:

 错误:char数组的初始化字符串太长

并接受#2 #3


gcc对所有语句给出以下错误:

 错误:从'const char *'到'char的无效转换'[-fpermissive] 

,另外还有#3 给出错误:

 错误:']'令牌

那么,对于该代码是否格式正确,该语言怎么说?


我想知道当前的规则,但我也会有兴趣知道是否在以前的语言版本中对此进行了更改。

解决方案

好的,这很容易跟踪。 {} 的存在意味着正在执行列表初始化,因此我们可以访问规范中我们最喜欢的部分: [dcl.init.list] / 3


对象在情况1中初始化为 char [4] 。 braced-init-list不是指定的初始化程序,因此将忽略3.1。 char [4] 不是一个类,因此将忽略3.2。 将我们带到3.3


否则,如果 T 是一个字符数组,并且初始值设定项列表中有一个元素是一个适当类型的字符串-文字([dcl.init.string]),则按照该小节中的描述执行初始化。


Well, char [4 ] 绝对是一个字符数组,并且初始化列表肯定包含一个元素,并且该元素实际上与字符数组的类型匹配。因此,我们去 [dcl.init.string]


告诉我们(一种流行的方式):


字符串字面量值的连续字符初始化


但下一段警告:



好,这会使#1格式错误。


因此,我们重做 char [5] 的过程。但这不会触发,因为5足够大。


最后,我们来看 char [] 。就初始化而言,这与使用数字没有什么不同。 char [] 是一个字符数组,因此它遵循上述规则。 C ++ 17会在 new 表达式中使用 char [] 阻塞,但 C ++ 20很好用


如果type-id或new-type-id表示未知界限的数组类型([dcl.array]),则不应省略new-initializer;分配的对象是一个具有n个元素的数组,其中n是由new-initializer中提供的初始元素的数量([dcl.init.aggr],[dcl.init.string])确定的。


这意味着#2和#3应该是合法的。因此,GCC使它们格式错误是错误的。而且由于错误的原因,它会导致#1格式错误。


For the following program:

int main() 
{
    new char[4] {"text"};  // #1
    new char[5] {"text"};  // #2
    new char[] {"text"};   // #3
}

clang gives an error for #1 which says:

error: initializer-string for char array is too long

and accepts #2 and #3.

gcc gives the following error for all statements:

error: invalid conversion from 'const char*' to 'char' [-fpermissive]

and in addition for #3 it gives the error:

error: expected primary-expression before ']' token

So what does the language say about whether this code is well-formed?

I want to know the current rules, but I'd also be interested to know if this has this changed in previous versions of the language.

解决方案

OK, this is pretty simple to trace. The presence of {} means that list initialization is being performed, so we get to visit our favorite part of the spec: [dcl.init.list]/3.

The object being initialized in case 1 is a char[4]. The braced-init-list is not a designated initializer, so 3.1 is ignored. char[4] is not a class, so 3.2 is ignored. That brings us to 3.3:

Otherwise, if T is a character array and the initializer list has a single element that is an appropriately-typed string-literal ([dcl.init.string]), initialization is performed as described in that subclause.

Well, char[4] is definitely a character array, and the initializer list definitely contains a single element, and that element does in fact match the type of the character array. So off to [dcl.init.string] we go.

That tells us (after a fashion):

Successive characters of the value of the string-literal initialize the elements of the array.

But the next paragraph warns:

There shall not be more initializers than there are array elements.

Well, that makes #1 ill-formed.

So, we redo the process for char[5]. And that doesn't trigger, since 5 is sufficiently large.

Lastly, we come to char[]. Which is no different from using a number, as far as initialization is concerned. char[] is an array of characters, so it follows the above rules. C++17 would choke on using char[] in a new expression, but C++20 is fine with it.

If the type-id or new-type-id denotes an array type of unknown bound ([dcl.array]), the new-initializer shall not be omitted; the allocated object is an array with n elements, where n is determined from the number of initial elements supplied in the new-initializer ([dcl.init.aggr], [dcl.init.string]).

Which means that #2 and #3 are supposed to be legal. So GCC is wrong to make them ill-formed. And it makes #1 ill-formed for the wrong reason.

这篇关于哪些具有char数组的新表达式格式正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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