cppcheck 警告:访问转发变量
Posted
技术标签:
【中文标题】cppcheck 警告:访问转发变量【英文标题】:cppcheck warning: access of forwarded variable 【发布时间】:2021-08-25 13:25:03 【问题描述】:关于以下代码
#include <utility>
template <int i = 0, class F, typename... ArgsType>
void g(F&& f, ArgsType&&... args)
if constexpr (i < 1)
f(std::forward<ArgsType>(args)...);
g<1>(std::forward<F>(f), std::forward<ArgsType>(args)...);
cppcheck --enable=all
的运行会给出以下警告:
Checking test.hpp ...
test.hpp:8:53: warning: Access of forwarded variable 'args'. [accessForwarded]
g<1>(std::forward<F>(f), std::forward<ArgsType>(args)...);
^
test.hpp:7:7: note: Calling std::forward(args)
f(std::forward<ArgsType>(args)...);
^
test.hpp:8:53: note: Access of forwarded variable 'args'.
g<1>(std::forward<F>(f), std::forward<ArgsType>(args)...);
^
这个警告是什么意思,为什么会触发它?
【问题讨论】:
Forwarding the same value to two or more functions 【参考方案1】:它警告您,您的代码在潜在移动后使用了变量。
std::vector<int> v1, 2, 3;
g([](auto v_) , std::move(v));
我们通过移动将v
传递给函数(因此我们传递了一个右值引用给它)。当它将在调用f(std::forward<ArgsType>(args)...)
中转发时,参数v_
将通过窃取v
的内部来初始化。之后再次使用它(通过引用)是不明智的,因为它被定义为处于“有效但未指定的状态”。在这种状态下使用它可能会导致微妙且难以检测的问题。
除非一个类型记录了在它们被移动后可以使用它的对象,我们唯一能做的真正有效的操作就是给它一个新的值。您的代码没有这样做。
【讨论】:
【参考方案2】:当你这样做时
f(std::forward<ArgsType>(args)...);
您正在使用完美转发将所有args...
传递给f
。这意味着如果args...
中的任何一个是右值,并且如果f
从该右值移动到函数参数或函数内的变量,那么args...
中的对象现在将处于从状态移动,意味着它的价值现在已经消失了。然后当你重用args...
g<1>(std::forward<F>(f), std::forward<ArgsType>(args)...);
您现在可以使用已移动其内容且不再可用于读取的对象。这就是您收到警告的原因。如果你想同时调用这两个函数,你不能使用完美转发。
【讨论】:
以上是关于cppcheck 警告:访问转发变量的主要内容,如果未能解决你的问题,请参考以下文章
cppcheck警告:变量未在带有初始化初始化的构造函数中实例化
在声纳中使用 C++ 社区插件的问题。 Cppcheck 不起作用
如何使用 stdint.h 的 int64_t 变量(cpcheck 认为它是有符号整数)防止 %"PRIi64" (%lld) 的 cppcheck (v1.72) 警告