Re: Question about static class objects

From: Tom Roberts <tjrob_at_fnal.gov>
Date: Tue, 27 May 2008 13:44:45 -0500


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 - 20:45:21 CEST

This archive was generated by hypermail 2.2.0 : Tue May 27 2008 - 23:50:01 CEST