传递未初始化的变量作为引用参数是否属于未定义行为?

8

I have the following code:

#include <iostream>

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

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

这段代码在C++中是否会引发未定义行为?g++编译它时没有任何警告,并且代码打印出了5(是否符合预期?)。

3个回答

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

1
关键在于对未初始化值进行左值到右值转换会导致未定义行为。 - Kerrek SB
没有未定义行为,这就是为什么没有 UB :-)(当然,有 rvalue,比如 50cout 行中 x 的 rvalue-to-lvalue 转换的结果)。但我只是试图给出一个更精确的“使用”定义。 - Kerrek SB

6
当评估产生不确定值时,除了一些例外情况(见C++14标准的§8.5/12),就会发生未定义行为。
在这种情况下,直到x被赋值后才使用它的值,所以这段代码是正确的。没有访问x的值来将引用绑定到它。(但是要注意:int也可以绑定到const double&,在这种情况下,值将被访问,并且将从该值创建一个新的临时double对象。)

2
不,这不会引起未定义行为,预期的打印值为5。 因为您将函数声明为void f(int& x)int&是引用类型,它会改变绑定到的变量的值,而不是复制它。
请注意,使用引用的真正未定义行为示例:
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() 完成后,引用将指向无效的内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接