奇怪的结构&GCC&clang(void*返回类型)
Strange construct & destructor syntax in GCC & clang (void* return type)
在编写一些C++代码(使用clang、x86_64-linux进行编译(时,我意外地编写了以下构造:
class Class {
*Class() {}
};
即构造函数名称前面带有星号(*(。
我注意到你可以在前面加任意数量的*;它也适用于析构函数,即
class Class {
********Class() {}
********~Class() {}
};
Clang编译它时没有任何错误或警告。
但是GCC发出警告
控制到达非无效功能的末尾
这让我相信我实际上是在声明一个返回类型为void*
(或void********
(的构造函数/析构函数。编写任何类型的带有值的返回语句都会产生错误(正如预期的那样(:
return nullptr;
return {};
...
有趣的是,生成的LLVM IR位代码正确地包含一个void函数:
define void @_ZN5ClassC2Ev(%struct.Class* %this) {...}
define void @_ZN5ClassD2Ev(%struct.Class* %this) {...}
搜索有关此的任何信息都没有找到任何结果。所以我的问题是:这个标准是符合C++还是GCC&Clang?或者可能是一些兼容性功能?如果正确,它的用例是什么。
它看起来像一个bug。因为它不符合标准。声明或定义构造函数的标准方法是在[class.cctor]/1:中
构造函数没有名称。在构造函数的声明中声明符是形式的函数声明符
ptr声明符(参数声明子句(noexcept说明符opt属性说明符seqptit其中ptr声明器仅由id表达式组成可选属性说明符seq和可选环绕括号,id表达式具有以下形式之一:
- 在属于类的成员规范但不是友元声明的成员声明中,id表达式是直接封闭类的注入类名
- 在属于类模板的成员规范但不是友元声明的成员声明中,id表达式为一个类名,用于命名立即封闭类模板;或
- 在命名空间范围的声明或友元声明中,id表达式是命名构造函数的限定id([class.qual](
类名不能是typedef名称。在构造函数中声明,可选decl说明符seq中的每个decl说明符应为friend、inline、explicit或constexpr。
正如您在我强调的部分中看到的,ptr-declarator
必须只是一个id表达式。或者用更简单、稍微不那么准确的术语来说,它必须只是类名。
那么,为什么可以在Clang和GCC中添加星号呢?他们似乎有一个bug,并且没有在这里对ptr-declarator
应用语义约束。这些约束很重要,因为纯语法确实允许使用星号。它在[dcl.dell]/4中(仅部分复制(:
声明器具有语法
ptr声明符:noptr声明器ptr运算符ptr声明符ptr运算符:*属性说明符seqoptcv限定符seqopt&属性说明符seqopt&属性说明符seq选项嵌套名称说明符*属性说明符seq-选择cv限定词seqopt
看到ptr-operator
位的语法了吗?它说*
可以出现在你放它的地方。或者&
甚至&&
。但我首先引用的声明中的语义使其成为非法。
因此,人们必须得出结论,这是GCC和Clang中的一个错误。
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 在c++类上调用void函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 在派生函数中指定void*参数
- C++为什么尽管我调用了void函数,它却不起作用
- 如何从void函数输出字符串
- 我应该使用什么来代替void作为变体中的替代类型之一
- 奇怪的结构&GCC&clang(void*返回类型)
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 引用一个已擦除类型(void*)的指针
- 将尾部调用void(i32,..)位转换为llvm::函数以获取FnAttribute
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- 如何将指针从一个void函数传递到另一个C++
- 为什么我在使用void函数时得到错误代码C2276
- void*到驱动程序中的UnicodeString
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- 指针没有更新它在void函数内部指向的值
- 不能将 "void *" 类型的值分配给类型 "TCHAR" 的实体
- 错误:在为指针赋值时,void值没有被忽略