clang-tidy 14版本对该代码报bugprone-use-after-move是否合理?
为什么clang-tidy会判定这段代码存在
bugprone-use-after-move? 先看这段代码:
struct test { test& foo(std::vector<int> const& v) { assert(v.size() == 1); return *this; } void bar(std::vector<int> v) {} }; void do_test() { std::vector<int> v = { 42 }; return test{}.foo(v).bar(std::move(v)); // <-- clang-tidy报错位置 }
clang-tidy报这个错的核心原因是C++标准没有规定成员函数链式调用中参数的求值顺序。具体来说,test{}.foo(v).bar(std::move(v))里,编译器可以选择先计算std::move(v),再调用foo(v);也可以先调用foo(v),再计算std::move(v)。
如果是前一种情况:先执行std::move(v)把vector v转换成右值,此时v进入已移动-from状态(虽然标准规定这种状态下对象仍需保持合法,但内容是未定义的),之后调用foo(v)时,foo里访问v.size()就是在使用一个已经被移动过的对象,这就构成了“移动后使用”的问题。
clang-tidy会检测到这种潜在的求值顺序风险——哪怕实际运行时可能没出问题,但从标准和代码安全性角度,这种写法存在未定义行为的隐患,所以会触发bugprone-use-after-move警告。
内容的提问来源于stack exchange,提问作者vladon
相关产品推荐
相关产品推荐

