Mar*_*ark 8 c++ visual-c++ language-lawyer delete-operator incomplete-type
以下代码使用编译和链接Visual Studio
(2017和2019都使用/permissive-
),但不使用gcc
或进行编译clang
。
foo.h
Run Code Online (Sandbox Code Playgroud)#include <memory> struct Base { virtual ~Base() = default; // (1) }; struct Foo : public Base { Foo(); // (2) struct Bar; std::unique_ptr<Bar> bar_; };
foo.cpp
Run Code Online (Sandbox Code Playgroud)#include "foo.h" struct Foo::Bar {}; // (3) Foo::Foo() = default;
main.cpp
Run Code Online (Sandbox Code Playgroud)#include "foo.h" int main() { auto foo = std::make_unique<Foo>(); }
我的理解是,in main.cpp
中的Foo::Bar
必须是完整类型,因为in中尝试将其删除~Foo()
,它是隐式声明的,因此在访问它的每个翻译单元中都是隐式定义的。
但是,Visual Studio
不同意,并接受此代码。此外,我发现以下更改使Visual Studio
代码遭到拒绝:
(1)
非虚拟(2)
内联-即Foo() = default;
或Foo(){};
(3)
在我看来,Visual Studio
在以下情况下使用它的地方似乎都没有定义隐式析构函数:
取而代之的是,它似乎仅在转换单元中定义了析构函数,该单元中还包含第二种条件下的构造函数定义。
所以现在我想知道:
Visual Studio
?更新:我已经提交了错误报告https://developercommunity.visualstudio.com/content/problem/790224/implictly-declared-virtual-destructor-does-not-app.html。让我们看看专家对此的看法。
我相信这是 MSVC 中的一个错误。至于std::default_delete::operator()
,标准说[unique.ptr.dltr.dflt/4]:
\n\n\n备注:如果 T 是不完整类型,则程序格式错误。
\n
由于没有“不需要诊断”子句,因此需要符合要求的 C++ 编译器来发出诊断 [intro.compliance/2.2]:
\n\n\n\n\n\n\n如果程序包含违反任何可诊断规则的行为或……,符合要求的实现应发出至少一条诊断消息。
\n
\n\n\n可诊断规则集由本文档中的所有句法和语义规则组成,但包含明确表示法\xe2\x80\x9cno 诊断需要\xe2\x80\x9d 或被描述为导致\xe2\x80 的规则除外\x9c 未定义行为\xe2\x80\x9d。
\n
GCC 用于static_assert
诊断类型完整性。MSVC 似乎不执行这样的检查。如果它默默地传递一个参数std::default_delete::operator()
to delete
,那么,这会导致未定义的行为。这可能与你的观察相符。它可能有效,但在文档保证它(作为非标准 C++ 扩展)之前,我不会使用它。
归档时间: |
|
查看次数: |
145 次 |
最近记录: |