c++ - 与在新表达式中解析类型 ID 相关的 gcc 发出错误
问题描述
这个节目
#include <cstddef>
int main()
{
const std::size_t N1 = 2;
const std::size_t N2 = 3;
int ( **p )[N1] = new ( int ( *[N2] )[N1] );
}
不使用编译器 C++ gcc HEAD 10.0.0 20190 进行编译。
编译器发出错误
prog.cc: In lambda function:
prog.cc:8:40: error: expected '{' before ')' token
8 | int ( **p )[N1] = new ( int ( *[N2] )[N1] );
| ^
prog.cc: In function 'int main()':
prog.cc:8:34: error: no match for 'operator*' (operand type is 'main()::<lambda()>')
8 | int ( **p )[N1] = new ( int ( *[N2] )[N1] );
prog.cc:8:47: error: expected type-specifier before ';' token
8 | int ( **p )[N1] = new ( int ( *[N2] )[N1] );
| ^
但是,该程序使用 clang HEAD 10.0.0 编译。
指针类型 ID 规范是模棱两可的还是确实是 gcc 错误?
编辑:顺便说一句,如果要删除外括号,例如
int ( **p )[N1] = new int ( *[N2] )[N1];
然后 clang 也会发出一个引用 lambda 的错误
prog.cc:8:38: error: expected body of lambda expression
int ( **p )[N1] = new int ( *[N2] )[N1];
^
解决方案
据我所知,这绝对是最新版本的 GCC 中的一个错误。据推测,GCC 正在尝试将( int ( *[N2] )[N1] )
部分解析为new-placement,即带括号的表达式列表。Nowint (
被解释为函数式转换等。
每个新表达式:
new-expression :
::
optnew
new-placement opt new-type-id new-initializer opt
::
optnew
new-placement opt(
type-id)
new-initializer opt
关于new-placement与(
type-id 没有特殊的消歧规则,因此如果不能将其解释为expression-list)
,则应将其解释为type-id。
EDIT部分是每个[expr.new]/4的语法错误:
[ 注意:new-expression的new-type-id中的括号会产生令人惊讶的效果。[ 示例:
new int(*[10])(); // error
格式错误,因为绑定是
(new int) (*[10])(); // error
相反,new
运算符的显式括号版本可用于创建复合类型的对象:
new (int (*[10])());
分配一个包含 10 个函数指针的数组(不带参数并返回int
)。— 结束示例 ] — 结束注释 ]
推荐阅读
- php - PHP文件如何通过这个回调参数知道和处理一个函数?
- javascript - Raspberry Pi 3 B+、ONOFF(节点)和 Sparkfun 大数字驱动程序出现问题
- node.js - 节点请求模块适用于本地主机,但在 Heroku 中返回“管道中未处理的流错误”,
- java - java.lang.IndexOutOfBoundsException的问题如何解决:Index: 0, Size: 0
- python - 遍历 SQLAlchemy 关系 - 确定喜欢帖子的用户
- javascript - 我们可以在单个三元条件下检查多个值吗?
- php - 使用循环在数组上添加项目
- php - 如何在作曲家中启用 tls / ssl 保护
- laravel - 当我将我的 laravel 项目上传到实时服务器时,只有主页正常工作,其他控制器和视图不工作
- python - 在 Heroku 上部署 Flask 并隐藏数据库密钥