【问题标题】:What happens when I try to run a constexpr function inside a non constexpr function?当我尝试在非 constexpr 函数中运行 constexpr 函数时会发生什么?
【发布时间】:2019-03-03 14:00:38
【问题描述】:

标题可能具有误导性,不知道如何解释,但我将提供一个示例。

所以我有这个结构:

struct mom {
public:
    static constexpr auto create(int i) {
        return a(i);
    }

    struct a {
        int* m_a;

        constexpr a(int i) : m_a(&i) {
            change();
        }

        constexpr void change(void) {
            *m_a += 100;
        }

        struct b {
        public:
            static int get(a* import) {
                int* arr = new int[10];
                arr[1] = *import->m_a;

                return arr[1];
            }
        };
    };
};

我这样称呼它:

printf("%d", mom::a::b::get(&(mom::create(10))));

它应该在编译时将 10(或您给它的任何其他值)加 100,然后在运行时将其存储到动态数组中并返回给您。

这段代码几乎与我的项目完全相同,但它有一个问题:它不是将值加 100,而是返回一个随机大数 (-95321314)。我试过调试它,一切都很好,直到我调用 get() 函数,我不知道发生了什么导致这个

有什么想法吗?

【问题讨论】:

  • FWIW,Clang 给了我一个nice warning
  • @chris 你是对的,现在正在寻找修复它

标签: c++ constexpr compile-time


【解决方案1】:

问题是m_a 是一个指向临时的指针,一旦堆栈展开,该临时的进一步使用是未定义的。

具体来说,对mom::create(10) 的调用返回一个结构a,其成员m_a 不再指向有效的内存区域。该成员的后续使用将是未定义的(例如,复制到 get() 中的 b 的数组中)


一个简单的“修复”是更改m_a(&i) -> m_a(new int(i)),尽管请注意这会引入内存泄漏并完全改变内存布局。由于我不清楚您的设计目标是什么,因此这是让事情“正常工作”的合理替代方案。

【讨论】:

  • 你很有可能是对的。我正在尝试找到一种方法将 get() 函数移动到 struct a 中,看看它是否有效。这很难,因为我希望所有内容都在 1 行中,并且我不能使其成为静态
  • 是的@Bozz,我添加了一个“修复”,尽管没有更多关于您的设计目标的信息,很难知道这是否有帮助
  • 构造函数是一个 constexpr 构造函数,因为我想在编译时执行此操作,正如我所说。你确定这行得通吗?
  • 添加了另一个包含 m_a 的外部结构,并把它代替了 m_a,它现在以某种方式工作。希望它能持续下去,因为我不知道它为什么起作用
猜你喜欢
  • 1970-01-01
  • 2018-07-10
  • 2021-09-01
  • 1970-01-01
  • 2017-05-27
  • 2013-12-24
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
相关资源
最近更新 更多