Hi Tom,
> Apparently I simplified it too much, and you took issue with C++ style
> rather than the actual problem (though your workaround does work).
Actually I did not take issue with C++ style [really :) I did not],
I was merely mentioning thatthe only working work-around within CINT
just happens to be better style :)
(i.e. it is not important compared to the fact that one work and one does
not)
> I'm astounded this has not come up before -- this is a standard
> way to keep track of all instances of class Zap.
It actually has been already encountered before and partially fixed.
However
this is a difficult/intrigate issue and we decided to postpone a real
complete solution until the merge with Reflex is done (especially since
there
is a perfectly valid (and arguably better :)) work-around)
> Making list not be a class variable, but rather a local static object in
> an accessor function (as you suggest), complicates the code more than I
> want to do (list is used several dozen times, and there are three such
> TList-s).
This is indeed unfortunate :(. Hopefully, in the example I provided, the change needed on the call site is minimal (replace 'list' with 'list()')
> Note that making try() not inline (separating its definition from the
> class declaration) did not help.
Indeed, this won't work any better, the issue is that the
initialization/constructor
of the object is not done correctly.
Cheers,
Philippe.
PS.
> The above code is straightforward, reasonable, and standard C++,
> and it ought to work; I'm astounded this has not come up before --
> this is a standard way to keep track of all instances of class Zap.
Well :), even in C++, this has many caveat, you have no control/guarantee
of when the class static data member will be initialized and using this
member during the shared library loading is __in C++__ undefined
behavior.
And, yes, this does not apply to your specific case and CINT ought to
function properly in this case; it does not and it is hard to fix :(
-----Original Message-----
From: owner-roottalk_at_root.cern.ch [mailto:owner-roottalk_at_root.cern.ch] On
Behalf Of Tom Roberts
Sent: Tuesday, May 27, 2008 1:45 PM
To: 'ROOT Talk'
Subject: Re: [ROOT] Question about static class objects
Apparently I simplified it too much, and you took issue with C++ style rather than the actual problem (though your workaround does work). In my real code, list is used only within class Zap, and that fails:
file zap.C now contains:
class Zap { static TList list; public: static void try() { list.Clear(); } }; TList Zap::list;
$ root -l
The Root User's Guide is at /Users/tjrob/root/Root_Users_Guide_5_12.pdf
root [0] .L zap.C
root [1] Zap::try()
Note that making try() not inline (separating its definition from the class declaration) did not help.
This happens to be root 5.14 on Mac OS X (Tiger), but the problem exists in 5.16 and 5.18 on Linux as well (and probably other releases and OSs).
Making list not be a class variable, but rather a local static object in an accessor function (as you suggest), complicates the code more than I want to do (list is used several dozen times, and there are three such TList-s). But I suppose I can put a non-static TList& into the class and initialize it as you suggest. The above code is straightforward, reasonable, and standard C++, and it ought to work; I'm astounded this has not come up before -- this is a standard way to keep track of all instances of class Zap.
Tom Roberts
Philippe Canal wrote:
> Hi Tom,
>
> Use:
>
> class Zap {
> public:
> TList &list();
> };
>
> TList &Zap::list() {
> static TList list;
> return list;
> }
>
> which anyway is slightly better in term of C++ style :)
>
> Cheers,
> Philippe.
>
> -----Original Message-----
> From: owner-roottalk_at_root.cern.ch [mailto:owner-roottalk_at_root.cern.ch] On
> Behalf Of Tom Roberts
> Sent: Monday, May 26, 2008 1:12 PM
> To: 'ROOT Talk'
> Subject: [ROOT] Question about static class objects
>
> I am puzzled why this fails (Root 5.16 or 5.18, on Fedora Core 8).
>
> file zap.C contains:
> class Zap {
> public:
> static TList list;
> };
> TList Zap::list;
>
> $ root -l
> root [0] .L zap.C
> root [1] Zap::list.Clear();
> *** Break *** segmentation violation [....]
>
> But this works:
> $ root -l
> root [0] TList zap;
> root [1] zap.Clear();
> root [2] .q
>
>
> Any suggestions how to work around this?
>
>
> Tom Roberts
>
>
Received on Tue May 27 2008 - 21:00:11 CEST
This archive was generated by hypermail 2.2.0 : Thu May 29 2008 - 17:50:01 CEST