C++ g++;虚拟方法上的[[noreturn]]

C++ g++;虚拟方法上的[[noreturn]],c++,c++11,g++,C++,C++11,G++,我在清理g++编译器警告时遇到了一些麻烦 假设我有这门课: A类 { 公众: [[noreturn]]虚拟空间将_throw(){throw 0;} }; 在一个非void函数中,我调用将抛出而不返回 如果我按值执行此操作,即: intg() { A A; a、 你会扔吗; } 然后我没有得到任何-Wreturn类型的警告 如果我用指针来做: intg() { A A; A*aptr=&A; aptr->will_throw(); } 然后我得到“警告:函数中没有返回非void[-Wret

我在清理g++编译器警告时遇到了一些麻烦

假设我有这门课:

A类
{
公众:
[[noreturn]]虚拟空间将_throw(){throw 0;}
};
在一个非void函数中,我调用
将抛出
而不返回

如果我按值执行此操作,即:

intg()
{
A A;
a、 你会扔吗;
}
然后我没有得到任何
-Wreturn类型的
警告

如果我用指针来做:

intg()
{
A A;
A*aptr=&A;
aptr->will_throw();
}
然后我得到“警告:函数中没有返回非void[-Wreturn-type]的返回语句”

如果我从
A::will\u throw
的声明中删除
virtual
,那么在指针上调用它也不会产生警告。如果方法是纯虚拟的,则对引用调用该方法似乎会产生警告,否则不会


我找不到任何东西表明这是它应该如何工作的,而且这些案例都不会发出叮当声的警告。这是GCC中的一个bug吗?

由于函数是虚拟的,编译器不知道(没有跟踪赋值)通过指针(或引用)的调用是指向
a::will\u抛出
,而不是指向某个可能不是
noreturn
的重写函数。因为这只是一个警告,所以这两种行为(或从不警告,或总是警告!)都是一致的。

对我来说显然是一个bug。我可以用GCC 9重新编程,而Clang9似乎没有任何问题。这对我来说似乎是违反直觉的。虚拟函数本身具有属性
noreturn
,我认为就编译器而言,这足以保证重写不会返回。我理解关于属性对继承意味着什么存在一些模糊性,但我不知道有任何其他方法来指定这个意图。如果GCC当前的行为不是完全错误的,我仍然认为它可以改进。@squevee:鉴于
[[noreturn]]]
函数实际返回的行为是未定义的,将其传播到重写器似乎相当激烈(还有严格意义上的表达能力差:也许你的意思是永远不要使用基本实现,并将误用报告为例外)。我不确定我是否完全理解你的意思。问题不在于行为(或费用)对于可执行文件,在实际操作中也不需要在运行时通过错误检查来强制执行此意图。这一切都可以正常工作。但是编译器的警告表明它误解了我认为相当明确的意图。@squeve:我的观点是标准没有说
[[nodiscard]]
是继承的(有合理的理由),这似乎是GCC以这种方式对待它的一个很好的理由,即使对于咨询诊断也是如此。