Static const array initialization in classes

Hi,

I am trying to declare a static const array in a class header file using the syntax

(TrigGlobalBranch.h)

class TrigGlobalBranch : public BranchBase {
public:
        TrigGlobalBranch();
        ~TrigGlobalBranch(){}
private:
static const int    L1_Trigs_TBP_id[15];
}

I then try to initialize this array in the source file via
(TrigGlobalBranch.C)

#include "TrigGlobalBranch.h"
const unsigned int TrigGlobalBranch::L1_Trigs_TBP_id[15]={138,192,36,35,93,91,88,92,133,41,43,228,223,224,15};

However the compiler complains with

root [0] gROOT->ProcessLine(".L BranchBase.C+g")
(Long_t)0
root [1] gROOT->ProcessLine(".L TrigGlobalBranch.C+g")
Info in <TUnixSystem::ACLiC>: creating shared library /afs/cern.ch/user/t/tbalestr/public/17.2.2.2/HIDP3DAnalysis2011/MuonDPDSkimming/./TrigGlobalBranch_C.so
Error in <ACLiC>: Dictionary generation failed!
Info in <ACLiC>: Invoking compiler to check macro's validity
In file included from /afs/cern.ch/user/t/tbalestr/public/17.2.2.2/HIDP3DAnalysis2011/MuonDPDSkimming/./TrigGlobalBranch.h:14,
                 from /afs/cern.ch/user/t/tbalestr/public/17.2.2.2/HIDP3DAnalysis2011/MuonDPDSkimming/./TrigGlobalBranch.C:1:
/afs/cern.ch/user/t/tbalestr/public/17.2.2.2/HIDP3DAnalysis2011/MuonDPDSkimming/./BranchBase.h:89: error: ISO C++ forbids declaration of 'vector' with no type
/afs/cern.ch/user/t/tbalestr/public/17.2.2.2/HIDP3DAnalysis2011/MuonDPDSkimming/./BranchBase.h:89: error: expected ';' before '<' token
/afs/cern.ch/user/t/tbalestr/public/17.2.2.2/HIDP3DAnalysis2011/MuonDPDSkimming/./BranchBase.h:90: error: ISO C++ forbids declaration of 'vector' with no type
.
.
.

I thought this was the correct way to initialize static array members, but I’m obviously going wrong somewhere. Thanks for any help.

Can it be that in one place you really have “const int” while in the other “const unsigned int”?

Also, in the “TrigGlobalBranch.h” source code that you show, the “class TrigGlobalBranch” definition ends with a “}” while you should have “};”.

Also, have a look at your “BranchBase.h” lines 89 and 90 (±1). There seems to be a “vector” and an appropriate include file may be missing for that “SomeThing” (and so the compiler does not know what it is). Or maybe you simply miss "#include " or instead of “vector” you should have “std::vector”. Actually it is also possible that a “;” is missing in the preceding line.

[quote]Hi,

I am trying to declare a static const array in a class header file using the syntax

I thought this was the correct way to initialize static array members, but I’m obviously going wrong somewhere. Thanks for any help.[/quote]

Yes, you posted wrong code - it has nothing to do with error diagnostic you quoted. Either show the real code, or try to add #include (if you do not have it) and declare member as std::vector …

Your error messages can be easily reproduce with g++ and the following code-snippet:

class A{
   vector<int> a_;
};

int main()
{

}

As you can see, there is no static arrays here, but compiler:

  1. does not know the name ‘vector’
  2. does not like < after 'vector’
    etc. - so you have to include and do a correct declaration
#include <vector>

class A
{
   std::vector<int> a_;
};

int main()
{
}

Hi,

Sorry. The semicolon and const unsigned int are fine. I was careless with my copy/pasting. However, as you stated, the issue is most likely with my declaration. I have members of my base class (BranchBase) that are of type vector<vector > *var1 and vector<vector > *var2. So in the header file of my base class, I have

#include
#ifdef MAKECINT
#pragma link C++ class std::vector < std::vector >+;
#pragma link C++ class std::vector < std::vector >+;
#endif

Of my 2 derived classes, one has these vector<vector > *var1 and vector<vector > *var2 variables, and it compiles just fine. However, its the derived class with no members that are vectors that crashes. This is the class from which the first post’s text is taken from.

(TrigGlobalBranch.h header file)

#ifndef TrigGlobalBranch_h
#define TrigGlobalBranch_h

#define min_pt 500
#define MAXTRK 100000

#ifndef BranchBase_h
#include "BranchBase.h"
#endif

#include "TVector3.h"
#include <string>


class TrigGlobalBranch : public BranchBase {
public:
        TrigGlobalBranch();
        ~TrigGlobalBranch(){}

        void Set_Trig_and_Global_Branches(TTree *MyTree);
        void Fill_Trig_and_Global_Branches();
        float Theta(float nu_pz, float nu_px, float nu_py, float nu_pt);
        float Eta(float nu_theta);
        TVector3 missP(float trkThresh);
private:

        static const int    L1_Trigs_TBP[15];
        static const unsigned int L1_Trigs_TBP_id[15];
        static const string L1_Trig_TBP_Names    [15];
        static const int    L1_Trigs[15];
        static const unsigned int L1_Trigs_id[15];
        static const string L1_Trig_Names[15];
        static const  int    EF_Trigs[36];
        static const  unsigned int EF_Trigs_id[36];
        static const  string EF_Trig_Names    [36];

   Float_t   Myvx_x,Myvx_y;
   Float_t   Myvx_z;
   Float_t   Psi_Et_N,Psi_Et_P,Psi_E_N,Psi_E_P;
   Float_t   Centrality;

   TVector3  vSum;

   Float_t   nu_pt500;
   Float_t   nu_px500;
   Float_t   nu_py500;
   Float_t   nu_pz500;
   TVector3  lvTrk;

   };
#endif

(first few lines of TrigGlobalBranch.C where array initializations take place. no vector types in this source code)

const unsigned int TrigGlobalBranch::L1_Trigs_TBP_id[15]={138,192,36,35,93,91,88,92,133,41,43,228,223,224,15};
const int TrigGlobalBranch::L1_Trigs_TBP[15] = {0};

        const string TrigGlobalBranch::L1_Trig_TBP_Names[15]={"L1_TE50"          , // 1    138
                                                 "L1_ZDC_A_C"       , // 2    192 
                                                 "L1_ZDC_A_C_VTE50" , // 3     36

                                                 "L1_MU0_VTE50"     , // 4     35
                                                 "L1_MU4"           , // 5     93
                                                 "L1_MU11"          , // 6     91
                                                 "L1_MU15"          , // 7     88
                                                 "L1_MU20"          , // 8     92
                                                 "L1_TE10"          , // 9    133 
                                                 "L1_MU0_TE50"      , //10     41
                                                 "L1_MU4_TE50"      , //11     43

                                                 "L1_MBTS_1_1"      , //12    228
                                                 "L1_MBTS_2_2"      , //13    223
                                                 "L1_MBTS_3_3"      , //14    224
                                                 "L1_MBTS_4_4"      };//15     15

        const unsigned int TrigGlobalBranch::L1_Trigs_id[15]={138,192,36,35,93,91,88,92,133,41,43,228,223,224,15};

        const int TrigGlobalBranch::L1_Trigs[15] = {0};

       const string TrigGlobalBranch::L1_Trig_Names[15]={"L1_TE50"          , // 1    138
                                         "L1_ZDC_A_C"       , // 2    192 
                                         "L1_ZDC_A_C_VTE50" , // 3     36

                                         "L1_MU0_VTE50"     , // 4     35
                                         "L1_MU4"           , // 5     93
                                         "L1_MU11"          , // 6     91
                                         "L1_MU15"          , // 7     88
                                         "L1_MU20"          , // 8     92
                                         "L1_TE10"          , // 9    133 
                                         "L1_MU0_TE50"      , //10     41
                                         "L1_MU4_TE50"      , //11     43

                                         "L1_MBTS_1_1"      , //12    228
                                         "L1_MBTS_2_2"      , //13    223
                                         "L1_MBTS_3_3"      , //14    224
                                         "L1_MBTS_4_4"      };//15     15


        const unsigned int TrigGlobalBranch::EF_Trigs_id[36]={750,4152,935,937,288,286,684,685,837,801,802,834,803,819,945,944,815,814,836,759,757,758,762,760,761,753,751,752,818,816,817,756,754,755,701,700};
        const int TrigGlobalBranch::EF_Trigs[36] = {0};

       const string TrigGlobalBranch::EF_Trig_Names[36]={"EF_L1TE50_NoAlg"     , // 1    750
                                         "EF_L1ItemStreamer_L1_TE50" , // 2   4152
                                         "EF_mbZdc_a_c_L1VTE50_trk"  , // 3    935

                                         "EF_mu4_L1VTE50"  ,           // 4   937
                                         "EF_L1MU4_NoAlg"  ,           // 5   288
                                         "EF_L1MU11_NoAlg" ,           // 6   286
                                         "EF_L1MU15_NoAlg" ,           // 7   684
                                         "EF_L1MU20_NoAlg" ,           // 8   685

                                         "EF_mu4_MSonly_j15_a2hi_EFFS_L1TE10", //9  837
                                         "EF_mu10_MSonly_EFFS_L1ZDC"         , //10 801 
                                         "EF_mu13_MSonly_EFFS_L1ZDC"         , //11 802 
                                         "EF_2mu2_MSonly_EFFS_L1ZDC"         , //12 834  
                                         "EF_2mu4_MSonly_EFFS_L1ZDC"         , //13 803 

                                         "EF_mu4_mu2_MSonly_EFFS_L1ZDC"      , //14 819 
                                         "EF_mu4_MSonly_L1TE50"              , //15 945 
                                         "EF_mu4T_MSonly_L1TE50"             , //16 944

                                         "EF_mu4_MSonly_EFFS_L1TE50"         ,//17 815
                                         "EF_mu4_MSonly_EFFS_L1TE20"         ,//18 814
                                         "EF_mu4_MSonly_EFFS_L1TE10"         ,//19 836


                                         "EF_mu10_MSonly_EFFS_L1TE50"        ,//20 759
                                         "EF_mu10_MSonly_EFFS_L1TE10"        ,//21 757
                                         "EF_mu10_MSonly_EFFS_L1TE20"        ,//22 758

                                         "EF_mu13_MSonly_EFFS_L1TE50"        ,//23 762
                                         "EF_mu13_MSonly_EFFS_L1TE10"        ,//24 760 
                                         "EF_mu13_MSonly_EFFS_L1TE20"        ,//25 761

                                         "EF_2mu2_MSonly_EFFS_L1TE50"        ,//26 753 
                                         "EF_2mu2_MSonly_EFFS_L1TE10"        ,//27 751 
                                         "EF_2mu2_MSonly_EFFS_L1TE20"        ,//28 752 

                                         "EF_2mu4_MSonly_EFFS_L1TE50"        ,//29 818
                                         "EF_2mu4_MSonly_EFFS_L1TE10"        ,//30 816 
 "EF_2mu4_MSonly_EFFS_L1TE20"        ,//31 817

                                         "EF_mu4_mu2_MSonly_EFFS_L1TE50"     ,//32 756    
                                         "EF_mu4_mu2_MSonly_EFFS_L1TE10"     ,//33 754    
                                         "EF_mu4_mu2_MSonly_EFFS_L1TE20"     ,//34 755    
                                         "EF_mu6_MSonly_L1TE50"              ,//35 701 
                                         "EF_mu6_L1VTE50"                    ,//36 700
                                         };

maybe I need to add to the TrigGlobalBranch header
#include
#ifdef MAKECINT
#pragma link C++ class std::vector < std::vector >+;
#endif
???

The errors that you show in the first post explicitly mention “BranchBase.h” lines 89 and 90.

Maybe you could try the following (inspect any warnings and/or errors that appear):
root-config --cxx --cflags -O2 -W -Wall -c BranchBase.C
root-config --cxx --cflags -O2 -W -Wall -c TrigGlobalBranch.C

BTW. Looking at the “TrigGlobalBranch.h header file” that you show in the last post, you should add #include “TTree.h” (or at least a declaration “class TTree;”) and change “string” into “std::string”.

[quote]I thought this was the correct way to initialize static array members, but I’m obviously going wrong somewhere. Thanks for any help.[/quote]Well the static array intialization might be right but CINT does not like it at all. So try:#include "TrigGlobalBranch.h" #ifndef __CINT__ const unsigned int TrigGlobalBranch::L1_Trigs_TBP_id[15]={138,192,36,35,93,91,88,92,133,41,43,228,223,224,15}; #endif

Cheers,
Philippe.

Actually, my experience says that, the current CINT will survive static array initialization as long as the array is made of one of the fundamental types.
But you are right, it will not survive any static “const std::string” array initialization (and so at least these parts of the source code need to be hidden from CINT).

After implementing all of your suggestions, each class now compiles. Thank you. Here’s how it was done.

[ul]
prepend std:: to each of the stl template class members (vector, string, cout, endl, etc.)
for the initialization of the static const members, hide them from CINT (i.e.use #ifndef CINT member initialization #endif)
compile using root-config --cxx --cflags -O2 -W -Wall -c ClassName.C
[/ul]

I’ve got an idea … if one wants to “test” that an include file is correct … one can create a “trial.cxx” file: #include "MyIncludeFile.h" void trial(void) { return; } // just for fun (i.e. not really needed) and then:
root-config --cxx --cflags -O2 -W -Wall -c trial.cxx