gpt4 book ai didi

c++ - 标准是否允许在未创建类的实例时不隐式定义隐式虚拟析构函数?

转载 作者:行者123 更新时间:2023-12-02 01:50:08 24 4
gpt4 key购买 nike

同时思考this question ,我偶然发现了一些我不明白的东西。

标准说...

[class.dtor]/4

If a class has no user-declared destructor, a destructor is implicitly declared as defaulted. An implicitly-declared destructor is an inline public member of its class.

[class.dtor]/10

[...] If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.

[class.dtor]/7

A destructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used or when it is explicitly defaulted after its first declaration.

[basic.def.odr]/3

[...] A virtual member function is odr-used if it is not pure. [...]

所以现在我想知道这段代码是否应该编译:

#include <memory>

struct Base {
virtual ~Base() = default;
};

struct Bar;
struct Foo : Base {
std::unique_ptr<Bar> bar_{};
};

https://godbolt.org/z/B0wvzd

我认为 ~Foo()必须隐式定义,因为它是虚拟的,但它不会编译,因为 Bar本 TU 中不完整。然而代码可以在所有主要编译器中编译。

我错过了什么?

最佳答案

So now I'm wondering whether this code should compile:

您是否“想知道”是否 this complete program "should" compile

void f();
void g() { auto ff = &f; }
int main() {}

如果您假设它会编译,您认为代码会编译“多少次”? (它应该编译的是单一真理还是双重独立真理?)

  1. f() 以非使用方式“使用”(地址被分配给经过优化的局部变量)。
g():
ret
  • g() 本身甚至没有被使用
  • 任何“哑”链接器都可以看到,因为不需要 g(),所以不需要 f();假设“愚蠢”的编译器会假设 g() 中甚至需要 f()!

    但是未声明的函数 (f()) 显然是 ODR 使用的。您是否期望这种实现行为,或者您是否“想知道”并提出问题?

    如果您预计不会出现错误,您可能应该重新考虑整个“ODR 使用违规得到编译器的通过让我想知道”事情:

    实现不会诊断缺乏定义,他们不需要制定工作程序。

    他们需要取决于实现的巧妙程度,显然如果不需要f(),你可以使上面的参数1.变得更加复杂g() 中隐藏着复杂的代码。我故意举了一个简单的例子,一个在 -O0 有效的例子。

    [注意:这是 -O0 级别 g() 的汇编:

    g():
    push rbp
    mov rbp, rsp
    mov QWORD PTR [rbp-8], OFFSET FLAT:_Z1fv
    nop
    pop rbp
    ret

    如您所见,不依赖于符号f()。]

    知识取决于优化级别以及代码生成时提供的数据量(同时编译许多翻译单元可能会有所帮助)。

    对于非虚函数,该函数要么被需要的东西(另一个函数或使用该函数地址初始化的全局对象)所需要(即命名)。

    对于虚函数,获取知识要困难得多:知道重写器不会被调用并不像知道不是重写器的函数(包括非虚函数)那么简单,因为重写器可以当对 (g)lvalue 进行虚拟调用时,通过“后期绑定(bind)”进行调用。

    编译器可能无法准确地确定哪些虚拟函数永远不需要,具体取决于程序的复杂性(停止程序问题表明它们永远无法准确地知道所有程序),但是从未实例化的对象的非静态成员函数显然永远不需要

    关于c++ - 标准是否允许在未创建类的实例时不隐式定义隐式虚拟析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58543232/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com