【发布时间】: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