繁体   English   中英

为什么优化标志打开时返回值不正确?

[英]Why is the return value incorrect with optimisation flags on?

我(仅供我自己)练习 c++ 并尝试将 c# 属性“重新编码”到其中。 我知道它没用(我的意思是,我不会使用它)但是,我只是想看看这是否可能。

由于某些原因,使用以下代码,在最新的 clang / gcc 版本下,它不会在除-O0之外的每个优化标志下产生正确的结果(据我所知,这会禁用优化。)

#include <functional>
#include <iostream>

template<typename T>
class Property
{
private:
    using getType = std::function<const T&(void)>;
    using setType = std::function<void(const T&)>;

    T internal;

    getType get;
    setType set;
public:
    Property(const T &value) : internal{value}, get{[this] () { return internal; }}, set{[this](const T& value) { internal = value; }} {}
    Property(getType fnc) : get(fnc) {  }
    Property(getType fncGet, setType fncSet) : get(fncGet), set(fncSet) {  }

    Property(setType fnc) : set(fnc) {  }
    Property(setType fncSet, getType fncGet) : get(fncGet), set(fncSet) {  }

    Property<T> &operator=(T& value) { set(value); return *this; }

    operator const T&() const { return get(); }
};

int main(void)
{
    Property<int> hey(12);

    std::cout << hey << std::endl;

    return hey;
}

它似乎在 Visual Studio 编译器下表现正确,但我不确定。

我错过了标准的一部分吗? 我的代码不正确吗? clang / gcc / STL 中是否有错误?

我将我的代码放在名为 Godbolt 的网站上,以便在编译器之间轻松切换,我得到了同样不连贯的结果。

这是它为 c++14 / clang 14 打印的内容:

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
624203080

最后一个数字在运行之间发生变化,但不是第一个让我认为它只需要未初始化的数据。

你的问题是这部分: using getType = std::function<const T&(void)>; 结合get{[this] () { return internal; }} get{[this] () { return internal; }}

lambda 在这里不返回internal作为引用,因此返回了internal的副本,并且 - 在这里我不知道std::function是如何实现的 - std::function必须保存internal的副本但返回它作为对那个比悬空的副本的引用。

将其更改为get{[this] () -> T& { return internal; }} get{[this] () -> T& { return internal; }}似乎解决了这个问题。

您初始化的 lambda 按get返回,而不是按引用返回,这意味着返回的int不再存在于std::function机器中的某个位置。

您可以指定参考返回

[this] () -> const T& { return internal; }

注意,您应该使Property不可复制且不可移动,因为在复制或移动时,您无法在std::function成员中重新指向this捕获。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM