Subject: Re: C++ interface : frame.rewind() Extension (possible Bug)

From: Jan Wielemaker <[email-masked]>
Date: Tue, 29 Aug 2000 11:29:26 +0200

On Tue, 29 Aug 2000, you wrote:

>Bjarne Stroustrup wrote in his book 'C++' that a compiler can build 
>temporary variables and the construction and destruction of this
>helpers depends on the compiler implementation.
>I'll found nothing about the order of the execution of local destuctors.
>But my debuger say's that the PlQuery destructor is called befor the 
>PlFrame destructor.

Odd.  Do the extra braces help in your case too?

>one thing confuse me:
>
>if i remove the true at the end of config_oc1000/5 it works.

If you make illegal calls from C, anything can happen.  The
true disables last-call optimisation in the call to 
calc_oc_type, leading to a different stack-layout.

>on the oter hand it olso works without the c++ interface which
>indicates to an error in the C++ interface.

Yip.  I tried your C code and it runs fine.  It however is not
a correct translation of the C++.  The translation is:

void
test()
{ fid_t fid = PL_open_foreign_frame();
  term_t a0 = PL_new_term_refs(2);
  static predicate_t p;
  qid_t qid;
  char * cp;

  if ( !p )
    p = PL_predicate("a_kind_of", 2, NULL);

  PL_put_atom_chars(a0, (const char *)"human");

  qid = PL_open_query(NULL, PL_Q_NODEBUG, p, a0);

  if ( PL_next_solution(qid) )
  { PL_get_chars(a0+1,&cp, CVT_ALL);
    printf("out %s\n", (const char *)cp);
  }

  PL_rewind_foreign_frame(fid);  /* NOTE: swapped these two */
  PL_cut_query(qid);
  
  PL_close_foreign_frame(fid);
}

Now it becomes clear why the extra {} help: they force
the PL_cut_query() before the PL_rewind_foreign_frame().
I didn't look at the documentation, but from the code it
is obvious this doesn't work: PL_rewind_foreign_frame()
undoes all bindings and breaks down the stacks to the
corresponding PL_open_foreign_frame(), effectively destroying
the query.

	Regards --- Jan