【问题标题】:How to prevent returning a pointer to a temporary variable?如何防止返回指向临时变量的指针?
【发布时间】:2017-03-22 15:33:58
【问题描述】:

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

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 开启。

【问题讨论】:

  • 如果您使用-O2 编译,gcc 会捕获此错误:melpon.org/wandbox/permlink/KaXY4ktTM1vMNTiX
  • "如何防止这种情况发生?"只有一种解决方案 - 停止使用原始指针
  • 好吧,int* ptr() & { return &i; } 适用于您的具体情况,但您可以通过 int* fun(int i) { S s{i}; return s.ptr(); } 轻松解决问题。
  • @Slava 不是真的,引用也一样。此外,通过引用(指针)返回成员是有正当理由的。
  • @Slava 他真正的意思是“如何让编译器警告我,以便我知道修复它?”显然编译器一开始就不能阻止你这样做。

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


【解决方案1】:

我是一名 Cppcheck 开发人员。

我的项目还在持续集成中加入了 cppcheck,但它也无法接受。

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

考虑到 cppcheck 的正则表达式性质,这并不令人惊讶。

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

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

【讨论】:

  • 仅供参考:已创建有关此问题的票 trac.cppcheck.net/ticket/7812
  • 我承认我没有研究 cppcheck 的内部结构,并且可能认为它是基于自定义规则的定义方式的正则表达式。我从问题中删除了该评论,以免传播错误信息。
猜你喜欢
  • 2013-01-12
  • 1970-01-01
  • 2010-11-16
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多