libc++ 中 std::min 没有悬挂引用
No dangling reference for std::min in libc++
众所周知(或者应该是)将 std::min
的结果绑定到 const
引用是一个非常糟糕的主意,每当 std::min
的参数之一是一个右值,因为 const
引用绑定不会通过函数 return 传播。所以下面的代码
#include <iostream>
#include <algorithm>
int main()
{
int n = 42;
const int& r = std::min(n - 1, n + 1); // r is dangling after this line
std::cout << r;
}
应该会产生未定义的行为,因为 r
是悬空的。事实上,当使用 -Wall -O3
编译 gcc5.2 时,编译器会吐出
warning: <anonymous>
is used uninitialized in this function [-Wuninitialized]
然而,使用相同标志(甚至包括 -Wextra
)的 clang (llvm 7.0.0) 编译不会发出任何警告,程序似乎 "work",即显示 41
。
问题:clang使用的是std::min
的"safe"版本吗?就像一个版本,只要其中一个参数是右值,就使用一些 SFINAE 按值 return 吗?还是根本不需要发出任何诊断信息,程序 "happens" 就可以在此 UB 场景中产生 "right" 结果?
是UB。 libc++ 不会以任何方式保护您免受此影响。
众所周知(或者应该是)将 std::min
的结果绑定到 const
引用是一个非常糟糕的主意,每当 std::min
的参数之一是一个右值,因为 const
引用绑定不会通过函数 return 传播。所以下面的代码
#include <iostream>
#include <algorithm>
int main()
{
int n = 42;
const int& r = std::min(n - 1, n + 1); // r is dangling after this line
std::cout << r;
}
应该会产生未定义的行为,因为 r
是悬空的。事实上,当使用 -Wall -O3
编译 gcc5.2 时,编译器会吐出
warning:
<anonymous>
is used uninitialized in this function [-Wuninitialized]
然而,使用相同标志(甚至包括 -Wextra
)的 clang (llvm 7.0.0) 编译不会发出任何警告,程序似乎 "work",即显示 41
。
问题:clang使用的是std::min
的"safe"版本吗?就像一个版本,只要其中一个参数是右值,就使用一些 SFINAE 按值 return 吗?还是根本不需要发出任何诊断信息,程序 "happens" 就可以在此 UB 场景中产生 "right" 结果?
是UB。 libc++ 不会以任何方式保护您免受此影响。