RE: [ROOT] Comments on TFormula/Compile/DefinedValue

From: Philippe Canal (pcanal@fnal.gov)
Date: Wed Jun 11 2003 - 16:47:56 MEST


Hi Ole,

Thanks for the remarks.  I think you are correct on both count.  I will make
changes to TFormula to clarify and correct the situations.

Cheers,
Philippe.

-----Original Message-----
From: owner-roottalk@pcroot.cern.ch
[mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Ole Hansen
Sent: Tuesday, June 10, 2003 4:38 PM
To: roottalk@pcroot.cern.ch
Subject: [ROOT] Comments on TFormula/Compile/DefinedValue


I have lost a bit of time recently due to some features of the TFormula
class which do not seem to be adequately documented.  So I thought I'd
summarize them here for everyone's reference.  These comments
refer to ROOT 3.05/04, but should apply equally to virtually all ROOT
versions back to 2.x.

- TFormula violates a common good C++ programming practice: Never call a
  virtual function from a constructor!  TFormula calls the virtual method
  Compile() in its non-default constructor.  While this is convenient,
  it causes the usual problems associated with such style, viz. unexpected
  and/or incorrect behavior and the need for code duplication in derived
  classes. The source code comments are outright misleading and really
  should be changed!  Compile() calls Analyze(), which calls
  DefinedVariable().  DefinedVariable()'s documentation reads
  "This member function can be  overloaded in derived classes".
  Good luck doing so - it does not work unless one also re-implements the
  TFormula constructor in the derived class and calls Compile() from
  there.  This would be ok (unless  one is a style perfectionist) if
  only it was properly documented.
  Documentation improvements would be highly welcome.

- DefinedVariable() is supposed to work in conjunction with
  DefinedValue().  However, it seems that some initialization
  is missing in TFormula::Compile() to make this work reliably.
  While Compile() resets virtually everything else,
  it does _not_ reset the two member variables fNval and
  fAlreadyFound which control the behavior of the DefinedVariable/
  DefinedValue mechanism.  As a result, re-compiling an object derived
  from TFormula that uses this mechanism may produce unpredicable
  results.  For instance, suppose DefinedVariable("x") returns 0 when the
  object is constructed. Then some data changes (e.g. a new configuration
  is loaded) and DefinedVariable("x") now returns 1.  The application
  recompiles all formulas as a result of the configuration changes, which
  should take care of things.  Mysteriously, however, some formulas now fail
to
  produce sensible results. The reason is that during recompilation the
  object may think that a variable is already defined when it isn't,
  or use incorrect indices for variables during evaluation (in the example,
  DefinedValue(0) might be called to get the value of "x" when
  the call should be DefinedValue(1)).  Whether or not this occurs depends
  on the particulars of how DefinedVariable/DefinedValue are implemented
  and on the expression used.  That fNval and fAlreadyFound are not reset
  in Compile() looks like a bug that has gone unnoticed so far.
  If it is, could it be corrected?  Until it is, people need to work
  around it by implemeting a Compile() method in the derived class to
  reset those status variables.

Best regards,

Ole Hansen
Jefferson Lab






#################################################################
#################################################################
#################################################################
#####
#####
#####
#################################################################
#################################################################
#################################################################



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:12 MET