取z3::expr_vector内元素地址报临时对象警告的问题咨询
问题解答
z3::expr_vector取地址触发警告的原因
这是Z3 C++ API的设计预期。z3::expr_vector本质是对底层C接口Z3_ast_vector的轻量封装,它的operator[]不会返回内部元素的左值引用,每次调用x[i]时,都会从C层数组取出对应ast句柄,构造一个新的临时z3::expr对象返回。取临时对象的地址属于未定义行为,编译器的警告完全合理,z3::expr_vector本身就不对外暴露内部存储元素的直接指针。
是否可以改用std::vector<z3::expr>存储
完全可以,只要遵循以下注意事项即可:
- 保证所有
z3::expr对象的生命周期短于关联的z3::context,避免context销毁后expr持有野句柄 z3::expr本身是轻量的句柄包装类,拷贝开销极低,存储到std::vector不会有性能损失- 如果后续需要调用Z3要求传入
z3::expr_vector的接口,只需将std::vector中的元素逐个push_back到临时的z3::expr_vector即可适配
条件生成z3::expr*的正确写法
你原有写法的问题是取临时对象的地址,临时对象在所在表达式执行结束后就会被销毁,后续e会成为野指针,完全不可用。可以根据场景选择以下两种实现:
优先使用值存储(无需指针的场景)
z3::expr e; if (some condition) { e = ctx.bv_const("s", 1); } else { e = ctx.bv_const("s", 1); } // 后续直接使用e即可
必须使用指针的场景
保证指针指向的对象生命周期覆盖所有使用周期:
// 方式1:用局部变量存储后取地址 z3::expr opt1 = ctx.bv_const("s1", 1); z3::expr opt2 = ctx.bv_const("s2", 1); z3::expr* e; if (some condition) { e = &opt1; } else { e = &opt2; } // 方式2:用智能指针管理堆上对象 std::unique_ptr<z3::expr> e; if (some condition) { e = std::make_unique<z3::expr>(ctx.bv_const("s1", 1)); } else { e = std::make_unique<z3::expr>(ctx.bv_const("s2", 1)); } // 后续通过e.get()获取指针使用
内容的提问来源于stack exchange,提问作者harishankarv
相关产品推荐
相关产品推荐

