我在下面有这些代码。const auto&在这种情况下有什么问题,它导致了意外的输出。
使用 gcc-4.8.5 编译时它工作正常,但使用 gcc-4.9.2 得到意外输出。
如果我删除&in const auto&,它可以在两个 gcc 版本中正常工作。
// max_dim is a protobuf filed: const auto max_dim = msg.max();
// cat2_num is an element in std::vector<int32_t>: const auto cat2_num = vec[i]
const auto& res_num = std::max(1, std::min(max_dim, cat2_num));
LOG(ERROR) << res_num << ", " << max_dim << ", " << cat2_num
<< ", " << std::max(1, std::min(max_dim, cat2_num));
Run Code Online (Sandbox Code Playgroud)
输出:
-1392522416, 3, 1, 1
2, 3, 2, 2
3, 3, 3, 3
-1392522416, 3, 1, 1
3, 3, 6, 3
2, 3, 2, 2
-1392522416, 3, 1, 1
-1392522416, 3, 1, 1
2, 3, 2, 2
Run Code Online (Sandbox Code Playgroud)
============更新========
我无法使用这些代码重现未定义的行为:
-1392522416, 3, 1, 1
2, 3, 2, 2
3, 3, 3, 3
-1392522416, 3, 1, 1
3, 3, 6, 3
2, 3, 2, 2
-1392522416, 3, 1, 1
-1392522416, 3, 1, 1
2, 3, 2, 2
Run Code Online (Sandbox Code Playgroud)
输出:
1, 3, -1
1, 3, 0
1, 3, 1
2, 3, 2
3, 3, 3
3, 3, 6
Run Code Online (Sandbox Code Playgroud)
Nat*_*ica 10
您的代码具有未定义的行为。在
const auto& res_num = std::max(1, std::min(max_dim, cat2_num));
Run Code Online (Sandbox Code Playgroud)
该1是prvalue,所以暂时整数创建获取绑定到函数参数。这会没事的 max 就像
template <typename T> const T max(const T&, const T&);
Run Code Online (Sandbox Code Playgroud)
但相反,它被定义为
template <typename T> const T& max(const T&, const T&);
Run Code Online (Sandbox Code Playgroud)
因此,如果这1恰好是最大值,则max返回对创建的临时对象的引用。之后,临时对象被销毁1,res_num作为悬空引用留下。要修复代码,请进行res_num非引用,例如
const auto res_num = std::max(1, std::min(max_dim, cat2_num));
Run Code Online (Sandbox Code Playgroud)
现在你得到了正确值的副本。
1:在完整表达式的末尾销毁所有临时变量,并在其中创建