在编写一些C ++代码(使用clang,x86_64 linux编译)时,我不小心编写了以下结构:
With Worksheets(Choose(Arg1, Sheet1.Name, Sheet2.Name)) ' reference Sheet1 if Arg1=1 and Sheet2 if Arg1=2
With .Range("C2", .Cells(.Rows.Count, "C").End(xlUp)).Find(what:=chart_label(Arg2), LookIn:=xlValues, lookat:=xlWhole) ' search reference referenced sheet x-values range for current x-value
score = .Offset(, 2).Value ' assign 'score' the value of found cell offset two columns to the right
desc = .Offset(, -1).Value ' assign 'desc' the value of found cell offset one column to the left
End With
End With
即构造函数名称前带有星号(*)。
再尝试一点,我注意到您可以在前面加上任意数量的*;它也适用于析构函数,即
class Class {
*Class() {}
};
Clang编译时没有任何错误或警告。
GCC发出警告
控制到达非无效函数的结尾
这使我相信我实际上是在声明一个返回类型为class Class {
********Class() {}
********~Class() {}
};
(或void*
)的构造函数/析构函数。并用值编写任何类型的return语句都会产生错误(如预期):
void********
有趣的是,生成的LLVM IR位码正确包含一个void函数:
return nullptr;
return {};
...
搜索与此有关的任何信息都没有得到任何结果。所以我的问题是:这个标准符合C ++还是GCC和Clang的编译器前端中的错误?或者也许是一些兼容性功能?如果正确的话,用例是什么。
答案 0 :(得分:2)
它看起来像个错误。因为它不符合标准。声明或定义构造函数的标准方法在[class.ctor]/1中:
构造函数没有名称。在构造函数的声明中, 声明符是形式的函数声明符
ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt其中ptr声明符仅由一个id表达式组成, 可选的attribute-specifier-seq和可选的环境 括号,并且id表达式具有以下形式之一:
- 在属于类的成员规范但不是朋友声明的成员声明中,id-expression为 立即封闭类的注入类名称;
- 在属于类模板的成员规范但不是朋友声明的成员声明中,id-expression为 一个类名,用于命名当前实例化 立即封闭类模板;或
- 在名称空间范围的声明中或在朋友声明中,id-expression是限定构造函数的合格ID ([class.qual])。
类名称不得为typedef名称。在构造函数中 声明,可选decl-specifier-seq中的每个decl-specifier 应该是friend,inline,explicit或constexpr。
正如我在强调的部分中所看到的,ptr-declarator
仅必须是一个id表达式。或者用更简单,更不准确的术语来说,它必须只是类名。
那么,为什么要在Clang和GCC中添加星号?看来他们有一个错误,并且这里没有在ptr-declarator
上应用语义约束。这些限制很重要,因为纯语法允许带有星号。它位于[dcl.decl]/4中(仅部分复制):
声明符具有语法
ptr-declarator: noptr-declarator ptr-operator ptr-declarator ptr-operator: * attribute-specifier-seqopt cv-qualifier-seqopt & attribute-specifier-seqopt && attribute-specifier-seqopt nested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt
看到语法的ptr-operator
了吗?就是说*
可以出现在您放置它的位置。或&
甚至&&
。但是声明中的语义(我首先引用的段落)使其成为非法。
所以必须得出结论,这是GCC和Clang中的错误。