【问题标题】:Why my program return different results at optimization level of O0 and O2为什么我的程序在 O0 和 O2 的优化级别返回不同的结果
【发布时间】:2026-01-30 05:55:01
【问题描述】:

这是我的代码:

#include<iostream>

const int & Min(const int& a, const int& b);


int main() {
    using namespace std;

    auto&& val = Min(1,2);

    cout << val << endl;
    return 0;
}


const int & Min(const int& a, const int& b) {
    return a < b ? a : b;
}

如果我使用 O0 选项 g++ -O0 main.cpp -o main 编译它,结果是 1。如果我使用 O2 选项进行编译,g++ -O2 main.cpp -o main,则结果为 0。

为什么这会给出不同的结果?

【问题讨论】:

标签: c++ gcc compiler-optimization


【解决方案1】:

您的代码有undefined behavior

对于Min(1,2);,构造了从12初始化的两个临时对象,然后绑定到引用参数ab。请注意,临时对象会立即被销毁(在完整表达式之后)。 Min() 通过引用返回 ab;这意味着返回的引用总是悬空的,对其取消引用会导致 UB,即一切皆有可能。

编辑

文字(如12)不能直接绑定到引用,而是需要temporary

临时对象在 when a prvalue is materialized so that it can be used as a glvalue, which occurs (since C++17) 中创建 以下情况:

  • 将引用绑定到纯右值

【讨论】:

  • 为什么会有从 1 和 2 初始化的临时对象,因为它们是即时数字?我通过引用传递了它们,为什么它们仍然是临时的?
  • 知道了,那我怎样才能让这个函数接受参考以及即时数字呢?这个函数的正确形式是什么?
  • @coincheung 像auto val = Min(1,2); 一样使用它就可以了,即不要通过引用捕获返回值。或者将返回类型从const int&amp;更改为int
  • 这是否意味着数字12 从调用函数Min(1,2) 到返回值?它们只有在返回完成并且函数堆栈向后移动后才被销毁,并且是在函数体中进行操作的过程,它们仍然活着并且可用?
  • @coincheung 即使您将参数类型更改为按值传递,即int Min(int a, int b);,使用Min(1, 2),也会从12 复制构造两个对象,然后使用作为参数ab
最近更新 更多