强制clang在此C ++代码片段上生成编译错误 [英] Forcing clang to generate compilation error on this snippet of C++ code

查看:176
本文介绍了强制clang在此C ++代码片段上生成编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个无效的代码:

class X {
public:
    virtual void func() = 0;
};

class JustDeclared {
    X missing();
};


int main() { return 0; }

它无法在gcc下编译,因为不可能创建抽象类的实例 X ,并且恰好已将其声明为 JustDeclared :: missing()方法的返回值。

It doesn't compile under gcc because it's impossible to create an instance of an abstract class X, and exactly this has been declared as a return value of the JustDeclared::missing() method.

但是clang ++和Visual Studio可以毫无问题地编译此代码段。我怀疑这是由于在实际编译之前简单地剥离了AST的未使用部分。

But clang++ and Visual Studio compile this snippet without problems. I suspect that it's due to simply stripping out unused part of the AST before the actual compilation.

但是是否可以启用某些学究的方法?

But is it possible to enable some "pedantic" mode that will force clang to generate an error for this snippet?

推荐答案

直到C ++ 14以及原始发行版中会强制clang生成此代码段错误的模式?在C ++ 17版本中,对于Clang(见下文)和MSVC,这在Clang和MSVC中均被认为是一个错误,这可能是由于在函数定义时而不是在(第一个)函数声明时执行了抽象类类型诊断(违反ISO标准规则)。正如涵盖的与此问题相关的常见问题解答 所涵盖的那样,但是,对于C ++ 20和< a href = http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0929r2.html rel = nofollow noreferrer> P0929R2 Clang和MSVC实际上是正确的接受该程序,而GCC拒绝该程序是不正确的。如 P0636R3 ,P0929R2中所指定应该被认为是C ++ 17中的缺陷报告。

Up until C++14, and in the original release of C++17, this is considered a bug in both Clang and MSVC, for Clang (see below) and likely for MSVC due to abstract class type diagnostics being performed at the time of function definition rather than at (first) function declaration (contrary to ISO standard rules). As is covered by this related Q&A which branched off from this question, however, as of C++20 and P0929R2 Clang and MSVC are actually correct to accept the program, whereas GCC is incorrect to reject it. As specified in P0636R3, P0929R2 should be considered a defect report in C++17.

以下所有标准参考文献均引用 N4659:Kona工作草案/ C ++ 17 DIS 2017年3月。

根据 [class.abstract] / 3 [强调我的]


不得使用抽象类作为参数类型,作为函数返回类型或显式转换的类型。
可以声明对抽象类的指针和引用。
[示例:

An abstract class shall not be used as a parameter type, as a function return type, or as the type of an explicit conversion. Pointers and references to an abstract class can be declared. [ Example:

shape x;           // error: object of abstract class
shape* p;          // OK
shape f();         // error
void g(shape);     // error
shape& h(shape&);  // OK

-示例]

抽象类可能不能用作函数返回类型,因此即使不使用 JustDeclared ,您的程序也格式错误。

an abstract class may not be used as a function return type, and thus your program is ill-formed, even if JustDeclared is not used.

对于Clang,这是错误报告

For Clang, this is bug report

  • Bug 18393 - no error diagnostics emitted for abstract return types on CXXMemberDeclExpr

2016年。2014年提交了修复该错误的尝试:

which has been dormant since 2016. An attempt to fix the bug was submitted in 2014:

  • Fix for PR18393 - emit error when abstract type is returned or taken by value

,它们标识了相同的不合规之处符合以上引用的标准[强调我的]:

which identified the same non-compliance with the standard as quoted above [emphasis mine]:


...

...

随附的修补程序包含PR18393 [1]的修复程序的实现。根据标准,抽象类不应用作参数类型,函数返回类型或显式转换的类型。 (class.abstract $ 10.4.3)。

Attached patch contains the implementation of a fix for PR18393[1]. According to standard "An abstract class shall not be used as a parameter type, as a function return type, or as the type of an explicit conversion" (class.abstract $10.4.3).

当前,在定义方法
时检查类型是否不是抽象类,但我看不到在这种情况下,当声明函数/方法时,clang不应该尽早将
做为任何原因。

还附加了测试。

Currently, checking if type isn't abstract class is done when method is defined, but I don't see any reason why clang shouldn't do it as early as possible, in this case, when function/method is declared. Test also attached.

...

但是,补丁尚未完成,可以说似乎已经死在水中了。

The patch, however, is yet to be completed, and arguably seems dead in the water.


但是有可能启用某些学究的方法吗?强制clang对此代码段生成错误的模式?

But is it possible to enable some "pedantic" mode that will force clang to generate an error for this snippet?

如上所述,对于C ++ 20和C ++ 17(缺陷反向移植)Clang实际上是正确的接受程序。因此,即使这是直到C ++ 14(和无缺陷移植的C ++ 17)之前的错误,由于自P0929R2起该标准已更改为以前的标准,因此上述错误报告仍可能被弃用。

As covered above, for C++20 as well as C++17 (defect backporting) Clang is actually correct to accept the program. Thus, even if this was a bug up until C++14 (and the non-defect-ported C++17), the bug report above is likely to be deprecated as the standard has, as of P0929R2, changed into what was previously the buggy behaviour of Clang.

请注意,如果您不仅声明而且还定义了 JustDeclared :: missing(),则Clang会通过违反[class.abstract] / 3正确地将程序诊断为格式错误,它也适用于C ++ 20(/应用P0929R2之后)。

Note that If you not just declare but also define JustDeclared::missing(), Clang will correctly diagnose the program as ill-formed, by violation of [class.abstract]/3, which also holds for C++20 (/after applying P0929R2).

这篇关于强制clang在此C ++代码片段上生成编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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