从Z3CAPI包装实体 我在Z3中对枚举排序进行了实验,我注意到我可能对如何正确使用C和C++ API有一些误解。让我们考虑下面的例子。

从Z3CAPI包装实体 我在Z3中对枚举排序进行了实验,我注意到我可能对如何正确使用C和C++ API有一些误解。让我们考虑下面的例子。,z3,Z3,context z3_cont; Z3_symbol e_names[2 ]; Z3_func_decl e_consts[2]; Z3_func_decl e_testers[2]; e_names[0] = Z3_mk_string_symbol(z3_cont, "x1"); e_names[1] = Z3_mk_string_symbol(z3_cont, "x2"); Z3_symbol e_name = Z3_mk_string_symbol

   context z3_cont;
   Z3_symbol e_names[2 ];
   Z3_func_decl e_consts[2];
   Z3_func_decl e_testers[2];

   e_names[0] = Z3_mk_string_symbol(z3_cont, "x1"); 
   e_names[1] = Z3_mk_string_symbol(z3_cont, "x2"); 
   Z3_symbol e_name = Z3_mk_string_symbol(z3_cont, "enum_type");  
   Z3_sort new_enum_sort = Z3_mk_enumeration_sort(z3_cont, e_name, 2, e_names, e_consts, e_testers);

   sort enum_sort = to_sort(z3_cont, new_enum_sort);
   expr e_const0(z3_cont), e_const1(z3_cont);

/* WORKS!
   func_decl a_decl = to_func_decl(z3_cont, e_consts[0]);
   func_decl b_decl = to_func_decl(z3_cont, e_consts[1]);
   e_const0 = a_decl(0, 0);
   e_const1 = b_decl(0, 0);   
*/
   // SEGFAULT when doing cout
   e_const0 = to_func_decl(z3_cont, e_consts[0])(0, 0);
   e_const1 = to_func_decl(z3_cont, e_consts[1])(0, 0);

   cout << e_const0 << " " << e_const1 << endl;
context z3_cont;
Z3_符号e_名称[2];
Z3_func_decl e_consts[2];
Z3功能测试仪[2];
e_名称[0]=Z3_mk_字符串符号(Z3_cont,“x1”);
e_名称[1]=Z3_mk_字符串符号(Z3_cont,“x2”);
Z3_symbol e_name=Z3_mk_string_symbol(Z3_cont,“枚举类型”);
Z3_sort new_enum_sort=Z3_mk_enumeration_sort(Z3_cont,e_name,2,e_name,e_consts,e_testers);
sort enum_sort=to_sort(z3_cont,new_enum_sort);
expr e_const0(z3_cont),e_const1(z3_cont);
/*工作!
func_decl a_decl=to_func_decl(z3_cont,e_consts[0]);
func_decl b_decl=to_func_decl(z3_cont,e_consts[1]);
e_const0=a_decl(0,0);
e_const1=b_decl(0,0);
*/
//在做cout的时候犯错误
e_const0=to_func_decl(z3_cont,e_consts[0])(0,0);
e_const1=to_func_decl(z3_cont,e_consts[1])(0,0);
库特
  • 每当我们创建新的Z3 AST时,如果
    n
    的引用计数器为0,则Z3可能会对AST
    n
    进行垃圾收集。在有效的代码段中,在创建任何新AST之前,我们先包装
    e_consts[0]
    e_consts[1]
    。当我们包装它们时,智能指针将撞击它们的引用计数器。 这就是它起作用的原因。在崩溃的代码段中,我们包装
    e_consts[0]
    ,然后在包装
    e_consts[1]
    之前创建
    e_const0
    。因此,
    e_consts[1]
    引用的AST在我们有机会创建
    e_const1
    之前被删除

    此更改已在夜间版本中可用

  • Z3_符号
    不是参考计数对象。它们是持久的,Z3维护一个包含所有创建符号的全局表。我们应该将符号视为唯一的字符串

  • 注意,我们可以使用类
    symbol
    和构造函数
    symbol::symbol(context&c,Z3_symbol s)
    。函数
    到*
    用于将使用C API创建的对象与智能指针包装在一起。我们通常有一个函数<代码> toa<代码>,如果有一个C API函数返回一个<代码>一个对象,并且C++中没有函数/方法等价的。p>

  • 谢谢你的解释。我根据上次编辑更新了您回复中的常量名称,以便于代码理解。假设Z3不会垃圾收集仍然没有引用计数的对象,而我将逐渐包装它们(假设我有100个枚举常量在那里),这是否足够安全。正如您所说,只要引用计数器为零,Z3就可以对它们进行垃圾收集。Z3是多线程库,所以我只是想,如果GC恰好在一个单独的线程中工作,并且在我有机会包装它们之前收集Z3_AST,即使我计划并且没有制作任何新的AST:)是的,我们可以假设Z3在逐渐包装对象时不会进行垃圾收集。如果调用分配另一个AST的API,Z3将只对AST进行垃圾收集。关于多线程,Z3没有用于垃圾收集的单独线程。