【问题标题】:Is it undefined behavior to pass-by-reference uninitialized variable?传递引用未初始化的变量是未定义的行为吗?
【发布时间】:2016-02-10 03:33:30
【问题描述】:

我有以下代码:

#include <iostream>

void f(int &x) {
    x = 5;
}

int main() {
    int x;
    f(x);
    std::cout << x << std::endl;
    return 0;
}

此代码是否会调用 C++ 中未定义的行为? g++ 在没有任何警告的情况下编译它,并且代码打印出5(如预期的那样?)。

【问题讨论】:

    标签: c++ pass-by-reference undefined-behavior


    【解决方案1】:

    当评估产生不确定的值时会发生未定义的行为,但有少数例外(请参阅 C++14 标准的第 8.5/12 节)。

    在这种情况下,x 的值直到 x 被分配后才使用,所以这段代码没问题。 x 的值不会被访问以绑定对它的引用。 (但是,请注意:int 也可以绑定到 const double&amp;,在这种情况下,将访问值 ,并从该值创建一个新的临时 double 对象。 )

    【讨论】:

      【解决方案2】:

      此代码中没有未定义的行为。在赋值之前使用一个未初始化的变量是未定义的,但是传递引用并通过引用执行赋值是明确定义的。

      【讨论】:

      • 关键是未初始化值的左值到右值转换会导致UB。
      • 没有,这就是为什么没有 UB :-) (嗯,当然有个右值,例如50cout 行中 x 的右值到左值转换的结果。)但我只是想更准确地定义“使用”的含义。
      【解决方案3】:

      不,这不会调用未定义的行为,并且预期的打印值为 5。 由于您将函数声明为void f(int&amp; x),因此int&amp; 是一个引用类型,它会更改它所绑定的变量的值,而不是复制它。

      注意什么是引用未定义行为的真实示例:

      int& f() {
          int x = 5;
          return x; //return a reference of a variable that will not exist
          //after f finished
      } 
      
      int main() {
          std::cout << f() << std::endl; //undefined behavior 
      }
      

      这是未定义的行为,因为引用不负责保持分配的数据有效,如果它们是有效的,引用只会改变和读取值。所以在f() 完成后,引用将指向无效内存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-28
        • 2021-11-11
        • 1970-01-01
        • 2020-02-12
        • 1970-01-01
        • 1970-01-01
        • 2016-07-31
        • 1970-01-01
        相关资源
        最近更新 更多