2 A C++ interface to SWI-Prolog (Version 2)
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
    • Packages
      • A C++ interface to SWI-Prolog
        • A C++ interface to SWI-Prolog (Version 2)
          • Summary of changes between Versions 1 and 2
          • Introduction (version 2)
          • The life of a PREDICATE (version 2)
          • Overview (version 2)
          • Examples (version 2)
          • Rational for changes from version 1 (version 2)
          • Porting from version 1 to version 2
          • The class PlFail (version 2)
          • The class PlTerm (version 2)
          • The class PlTermv (version 2)
          • The class PlAtom - Supporting Prolog constants (version 2)
          • Unification and foreign frames (version 2)
          • The class PlRegister (version 2)
          • The class PlQuery (version 2)
          • The PREDICATE and PREDICATE_NONDET macros (version 2)
          • Exceptions (version 2)
          • Embedded applications (version 2)
          • Considerations (version 2)
          • Conclusions (version 2)

2.1 Summary of changes between Versions 1 and 2

Version 1 is in SWI-cpp.h; version 2 is in SWI-cpp2.h.

The overall structure of the API has been retained - that is, it is a thin layer on top of the interface provided by SWI-Prolog.h. Based on experience with the API, most of the conversion operators have been removed or deprecated, and replaced by "getter" methods. The overloaded constructors have been replaced by subclasses for the various types. Some changes were also made to ensure that the [] operator for PlTerm and PlTermv doesn't cause unexpected implicit conversions. 2If there is an implicit conversion operator from PlTerm to term_t and also to char*, then the [] operator is ambiguous in PlTerm t=...; f(t[0]) if f is overloaded to accept a term_t or char*.

More specifically:

  • The constructor PlTerm() is not available - instead, you should use the appropriate subclass' constructor (PlTerm_var(), PlTerm_atom(a), PlTerm_term_t(t), PlTerm_integer(i), PlTerm_int64(i), PlTerm_uint64(i), PlTerm_size_t(i), PlTerm_float(v), or PlTerm_pointer(p)).
  • Instead of returning false from a predicate to indicate failure, you can use throw PlFail(). The convenience function PlCheck(rc) can be used to throw PlFail(), if a false is returned from a function in SWI-Prolog.h
  • The "cast" operators (e.g., (char*)t, (int64_t)t) have been deprecated, replaced by "getters" (e.g., t.as_string(), t.as_int64_t()).3The form (char*)t is a C-style cast; C++'s preferred form is more verbose: static_cast<char*>(t).
  • The overloaded assignment operator for unification is deprecated; replaced by unify_term(), unify_atom(), etc., and the helper PlCheck().
  • Methods that return char* have been replaced by methods that return std::string to ensure that lifetime issues don't cause subtle bugs.4If you want to return a char* from a function, you should not do return t.as_string().c_str() because that will return a pointer to local or stack memory. Instead, you will need to change your interface to return a std::string and apply the c_str() method to it. These errors can sometimes be caught by specifying the Gnu C++ or Clang options -Wreturn-stack-address or -Wreturn-local-addr - Clang seems to do a better analysis.
  • Type-checking methods have been added: type(), is_variable(), is_atom(), etc.
  • PlString has been renamed to PlTerm_string to make it clear that it's a term that contains a Prolog string.
  • More PL_...(term_t, ...) methods have been added to PlTerm.
  • std::string and std::wstring are now supported in most places where char* or wchar_t* are allowed.
  • Most functions/methods that return an int for true/false now return a C++ bool.
  • The wrapped C types fields (term_t, atom_t, etc.) have been renamed from handle, ref, etc. to C_.5This is done by subclassing from Wrapped<term_t>, Wrapped<atom_t>, etc., which define the field C_, standard constructors, the methods is_null(), not_null(), reset(), and reset(v), plus the constant null.
  • A convenience class PlForeignContextPtr<ContextType> has been added, to simplify dynamic memory allocation in non-deterministic predicates.
  • A convenience function PlRewindOnFail() has been added, to simplify non-deterministic code that does backtracking by checking unification results.
  • PlStringBuffers provides a simpler interface for allocating strings on the stack than PL_STRINGS_MARK() and PL_STRINGS_RELEASE().

More details are given in section 2.6 and section 2.7.