alf*_*lfC 8 c++ static-analysis move clang clang-tidy
经过一番努力,我说服 clang 编译器和 clang-tidy(静态分析器)对移动后使用的情况发出警告。(参见/sf/answers/5197539721/)
int main(int, char**) {
a_class a;
auto b = std::move(a);
a.f(); // warns here, for example "invalid invocation of method 'f' on object 'a' while it is in the 'consumed' state [-Werror,-Wconsumed]"
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将变量设置为全局变量(或静态或惰性静态),则不再有警告。
a_class a;
int main(int, char**) {
auto b = std::move(a);
a.f(); // no warns here!
}
Run Code Online (Sandbox Code Playgroud)
请参阅此处: https: //godbolt.org/z/3zW61qYfY
是否可以在编译时对全局变量进行某种类型的移动后使用检测?或者即使在原则上也是不可能的?
注意:请不要讨论全局对象(我知道这是一个坏主意)或使用移动对象的合法性(我知道有些类是为此设计的)。这个问题是技术性的,涉及用于检测程序中某种容易出现错误的模式的编译器和工具。
完整的工作代码,clang ... -Wconsumed -Werror -std=c++11使用clang-tidy. clang 注释(扩展)帮助编译器检测模式。
#include<cassert>
#include<memory>
class [[clang::consumable(unconsumed)]] a_class {
std::unique_ptr<int> p_;
public:
[[clang::callable_when(unconsumed)]]
void f() {}
// private: [[clang::set_typestate(consumed)]] void invalidate() {} // not needed but good to know
};
a_class a;
int main(int, char**) {
// a_class a;
auto b = std::move(a);
a.f(); // global doesn't warn here
}
Run Code Online (Sandbox Code Playgroud)
我能找到的关于这个 clang 扩展的大部分信息都来自这里:Andrea Kling 的博客https://awesomekling.github.io/Catching-use-after-move-bugs-with-Clang-consumed-annotations/
您可以将cppcheck与performance和style检查一起使用。与cppcheck --enable=performance,style file.cpp您可以检查您的file.
例如,在以下代码中(简单的移动后使用):
#include <utility>
// Declare a global variable
int globalVariable = 0;
int main() {
// Move the global variable to a local variable
int localVariable = std::move(globalVariable);
// Access the global variable after it has been moved
return globalVariable;
}
Run Code Online (Sandbox Code Playgroud)
它会产生[my_file.cpp:8]: (performance) Access to moved-from object 'globalVariable'.并因此检测移动后使用的情况!:)
| 归档时间: |
|
| 查看次数: |
663 次 |
| 最近记录: |