首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用工会来防止破坏?

利用工会来防止破坏?
EN

Stack Overflow用户
提问于 2022-01-19 16:42:11
回答 1查看 136关注 0票数 4

相关:delete on析构函数如何防止堆栈分配?

首先,我意识到这种事情是玩火,诱惑UB。我要求更好地理解union的角落案例。

据我所知,如果我有一个具有c‘’tor和d‘’tor的类,并将其放入一个union中,编译器将迫使我告诉它如何处理构造和破坏。如图所示

代码语言:javascript
复制
#include <iostream>

struct S {
    int x;
    S() : x(-1) { std::cout << "S()" << std::endl; }
    ~S() { std::cout << "~S()" << std::endl; }
    static S& instance() {
        union DoNotDestruct {
            S value;
            DoNotDestruct() : value() {}
            ~DoNotDestruct() {}
        };
        static DoNotDestruct inst;
        return inst.value;
    }
};

int main() {
    return S::instance().x;
}

报告的只是建筑而不是破坏。

但是,如果我有一个删除的析构函数,那就不起作用了;我必须使用Place-new

代码语言:javascript
复制
#include <new>

// Placement-new version:
struct S0 {
    S0() {}
    ~S0() = delete;
    static S0& instance() {
        union DoNotDestruct {
            S0 value;
            DoNotDestruct() {
                // I believe value isn't constructed yet.
                new (&value) S0; // Placement-new.
            }
            ~DoNotDestruct() {} // Omit S0's d'tor.
        };
        static DoNotDestruct inst;
        return inst.value;
    }
};

// Init version:
struct S1 {
    S1() {}
    ~S1() = delete;
    static S1& instance() {
        union DoNotDestruct {
            S1 value;
            DoNotDestruct() : value{} {} // Why does this line want S1::~S1() to exist?
            ~DoNotDestruct() {} // Omit S1's d'tor.
        };
        static DoNotDestruct inst;
        return inst.value;
    }
};

https://godbolt.org/z/7r4ebszor

在这里,S0很高兴,但是S1在构造函数行上抱怨S1::~S1()被删除了。为什么?

我尝试添加noexcept,因为在class中,如果您有多个成员,那么如果后续的c‘’tors抛出,第0成员需要是可销毁的。看起来,即使是具有已删除的d‘’tor的类本身也不能保存一个不可摧毁的成员,即使c‘函数都是noexcept。它给出了与unionhttps://godbolt.org/z/jx3W1YEPf相同的错误

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-19 17:47:09

[class.dtor]/15说,如果可能调用的析构函数被定义为已删除,则程序的格式是错误的。

[class.base.init]/12说,类的潜在构造子对象的析构函数可能在非委托构造函数中被调用。

[特殊]/7说,所有非静态数据成员都有潜在的次对象构造,尽管这个句子有点奇怪,我认为(“对于一个类,.”)。

对于单成员类、联合类或noexcept,我不认为有任何例外。所以在我看来GCC对S1是正确的。

Clang也是Clang、GCC、ICC和MSVC中唯一不拒绝这个版本的编译器。

然而,对于S0来说,这一推理也适用,这也使得它的格式不正确。然而,四个编译器中没有一个同意这一点,所以我可能错了。

引用的措辞大多来自CWG第1424期。Clang和GCC (https://gcc.gnu.org/projects/cxx-dr-status.html)一样,将其目前的实施状况列为未知数(https://gcc.gnu.org/projects/cxx-dr-status.html)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70774468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档