Z3でいくつかの戦術を呼び出した後に列挙定数を使用する方法で説明されているように、Z3 で列挙型の並べ替えを試しています。そして、C と C++ の API を適切に使用する方法について誤解があるかもしれないことに気付きました。次の例を考えてみましょう。
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;
コードの 2 つのバリアントは、C エンティティ Z3_func_decl をスマート ポインターで適切にラップして、C++ API で使用できると思っていましたが、最初のバリアントだけが正しいようです。だから私の質問は
これは、2 番目の方法が機能しない正しい動作ですか? もしそうなら、そうすべきではない理由をよりよく理解するにはどうすればよいですか?
たとえば Z3_symbol e_name のように、ラップされていない C エンティティで何が起こるか - ここではラップせず、参照をインクリメントしません。それで、メモリは適切に管理されますか?安全に使用できますか?オブジェクトはいつ破棄されますか?
ちょっとした質問: C++ API に to_symbol() 関数がありませんでした。不要なだけですか?
ありがとうございました。