RE: [ROOT] LoadMacro and static variables

From: Philippe Canal (pcanal@fnal.gov)
Date: Fri Nov 29 2002 - 18:06:35 MET


Hi Richard,

You have hit one of CINT's file loading protection.  Typically, you may have
things like

	//File A.h
	class A {};

	//File B.h
	#include <A.h>
	class B { A a; };

In this case if the file A.h is reloaded after B.h, you have to also reload
B.h so that the class B is fixed up.  Of course this is only the simplest of
the cases.  So CINT has implemented an heuristic where if you try to reload
a file that contains more that just the definition of simple free standing
functions, all files that included this file are also reloaded.

Your case is one of those (doing gROOT->LoadMacro is equivalent (for the
purpose of this discussion to doing #include).  For example you may have
done:

	//a.C
	Int_t a ()
	{
	   static Int_t x0 = 200;
	   return x0;
	}

	//b.C
	void b()
	{
  	  gROOT->LoadMacro ("a.C");
  	  static Int_t b0 = a();
	}

To conserve the expected C++ semantic, once you reload a.C (where the value
of the static in a() may have changed), b0 should be reassigned.

In addition, reloading a function while it is being executed is not
permitted.  Hence the error message.

You can work around this protection (after making sure it is okay to do so)
by explicitly unloading the file before reloading it.

      //c.C
	void c()
	{
   	   static bool loaded = false;
	   if (loaded) gROOT->ProcessLine(".U a.C");
	   gROOT->LoadMacro ("a.C");
	   loaded = true;
	   a();
	}

Cheers,
Philippe

-----Original Message-----
From: owner-roottalk@pcroot.cern.ch
[mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Richard S. Holmes
Sent: Friday, November 22, 2002 12:10 PM
To: ROOTtalk
Subject: [ROOT] LoadMacro and static variables


Is there a problem with using TROOT::LoadMacro on a macro with static
variables?

To illustrate with a toy example: if file a.C contains:

========

void a ()
{
  static Int_t x0 = 200;
}

========

and file b.C contains:

========

void b()
{
  gROOT->LoadMacro ("a.C");
  a();
}

========

then if I try to load b.C and execute it, it works; but if I execute
it again, I get an error:

========

root [0] .L b.C
root [1] b()
root [2] b()
Function b() busy. loaded after
"/auto/mepdisk/src/happex/pan/./macro/b.C"
Error: G__unloadfile() Can not unload
"/auto/mepdisk/src/happex/pan/./macro/b.C", file busy  FILE:macro/b.C
LINE:3
*** Interpreter error recovered ***

========

If I remove the keyword "static" from a.C, this error does not occur.

I am using ROOT 3.03/09 under Red Hat 7.3.

(Of course I could omit the LoadMacro and just do .L a.C before
executing b(), but there are two objections to this.  First, in the
real world when a macro relies on several other macros to be loaded,
this becomes a nuisance.  Second, if the loaded macro alters the value
of the static variable when it executes, then the static variable
maintains its current value that way, while presumably if LoadMacro
were used successfully it should return the static variable to its
initial value... I should think.)

--
Richard S. Holmes, Research Assistant Professor
Physics Department, Syracuse University
Syracuse, NY 13244
(315) 443-5977



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:21 MET