c++ - 如何防止返回指向临时变量的指针?

标签 c++ pointers temporary static-code-analysis cppcheck

在最近的一次错误搜索中,我发现返回指向临时变量成员的指针存在问题。有问题的(简化的)代码是:

struct S {
    S(int i) : i(i) {}
    int i;
    int* ptr() { return &i; }
};

int* fun(int i) { return S(i).ptr(); }  // temporary S dies but pointer lives on

int main() {
    int* p = fun(1);
    return *p;  // undefined
}

如何预防? GCC 和 Clang 有 -Waddress-of-temporary-Wreturn-stack-address 但由于 ptr() 的作用,它们似乎松散了踪迹作为肮脏行为的中间人。它们仅在直接取指针时触发:

int* fun(int i) { return &S(i).i; }  // rightly fails to compile

我的项目还在持续集成中加入了 cppcheck,但它也无法使用(引发 here)。

哪种静态分析工具可以防止此类错误?

编辑:GCC 确实从 6.1.0 版开始使用 -Wreturn-local-addr 和(令人惊讶的)-O2 开启。

最佳答案

我是一名 Cppcheck 开发人员。

My project also incorporates cppcheck in continuous integration but it also can't pick it up.

有趣的错误。这是 cppcheck 想要警告的那种错误。我们有一些相关的检查,但不幸的是,这没有通过。

Not really surprising given the regex nature of cppcheck.

我个人不明白为什么有人说 cppcheck 是一个正则表达式工具。

它使用 AST、上下文敏感的值流分析等来检测错误。 GCC 和 Clang 也是如此。 Cppcheck 有时声称是一个正则表达式工具,但 GCC 和 Clang 不是。

关于c++ - 如何防止返回指向临时变量的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40496555/

相关文章:

C++ 模板别名(在特定地方使用)

c++ 构造函数和初始化程序行为。这5个代码有什么区别?

pointers - 为什么弱指针有用?

rust - 为什么临时借用是合法的?

c++ - Thrift 将可选转换为默认或必需

c++ - 将 C++ 数组指针的过去末尾转换为迭代器是否合法?

c - 找到节点后从链表中删除节点

rust - 为什么临时借用是合法的?

java - 拆分临时变量重构示例

c++ - 我如何创建一个线程安全的 QOffscreenSurface 供 OpenGl 使用