1

I would like to compile a C++ software which gives me a couple of compilation errors. This error is about a member function that cannot be resolved.

This question should contain everything needed to answer it. However, if that really was the case, I should have found the answer by now. So please feel free to browse the source code. All code in this question is not mine but licensed under the GPLv2.

The system I compile on is an IBM PowerPC 740 running Red Hat Enterprise Server 6.8. Using modules, I have enabled Clang 3.7. Everything gets cross-compiled for IBM PowerPC A2 chips, it is an IBM BlueGene/Q supercomputer. Those things should be taken care by my compilation script that sets the many configure and CXXFLAGS needed.

The compilation error that I currently get with the my current state (commit fee0a02) is this one:

bfmcommqmp.C:183:5: error: use of undeclared identifier 'gather'
    gather(result_cb, psi, dag);
    ^

The offending line is in this method definition in bfmcommqmp.C:

168 template <class Float>                                                          
169 void bfmcommQMP<Float>::comm_start(int result_cb, Fermion_t psi, int dag) {     
170     // gather the faces. Routines here are threaded.                            
171     // All threads cooperate in gathering.                                      
172                                                                                 
173     //  if ( this->isBoss() && (me == 0)) {                                     
174     //    this->Error("comm_start checking heap\n"); fflush(stdout);            
175     //    mcheck_check_all();                                                   
176     //    this->Error("comm_start mcheck_all");fflush(stdout);                  
177     //  }                                                                       
178                                                                                 
179     int me = this->thread_barrier();                                            
180                                                                                 
181     this->thread_barrier();                                                     
182                                                                                 
183     gather(result_cb, psi, dag);                                                
184                                                                                 
185     this->thread_barrier();                                                     
186     if (me == 0) {                                                              
187         comm_qmp_start(psi);                                                    
188     }                                                                           
189     this->thread_barrier();                                                     
190                                                                                 
191     return;                                                                     
192 }

This is of course part of the bfmcommQMP class. Looking at the associated header file, bfmcommqmp.h, one finds this class declaration:

  8 template <class Float>                                                          
  9 class bfmcommQMP : public bfmbase<Float> {                                      
 10   public:                                                                       
 11     // QMP thingy-me-bob's                                                      
 12     QMP_msghandle_t multi_handle[2];                                            
 13                                                                                 
 14     QMP_msgmem_t send_ops_msgmem_t[8];                                          
 15     QMP_msgmem_t recv_ops_msgmem_t[8];                                          
 16                                                                                 
 17     QMP_msghandle_t send_multi_handle;                                          
 18     QMP_msghandle_t send_handles[8];                                            
 19                                                                                 
 20     QMP_msghandle_t recv_handles[8];                                            
 21     QMP_msghandle_t all_handles;                                                
 22                                                                                 
 23     Float *simd_rbuf[8];                                                        
 24     Float *receive_area;                                                        
 25                                                                                 
 26     int num_op;                                                                 
 27                                                                                 
 28     virtual bool isBoss();                                                      
 29                                                                                 
 30     virtual void recv_init(void);                                               
 31     virtual void recv_end(void);                                                
 32                                                                                 
 33     virtual void comm_init(void);                                               
 34     virtual void comm_end(void);                                                
 35     virtual void comm(int result_cb, Fermion_t psi, int dag);                   
 36     virtual void comm_start(int result_cb, Fermion_t psi, int dag);             
 37     virtual void comm_qmp_start(Fermion_t psi);                                 
 38     virtual void comm_qmp_complete(void);                                       
 39     virtual void comm_merge(void);                                              
 40     virtual void comm_complete(int result_cb, Fermion_t psi);                   
 41     virtual void comm_gsum(double &val);                                        
 42     virtual void comm_gsum(double *val, int N);                                 
 43 };

It inherits from bfmbase. Jumping to the file bfm.h which is included in bfmcommqmp.h, we find the class definition, which contains two gather methods:

 133 template <class Float>                                                          
 134 class bfmbase : public bfmarg, public ThreadModel {                             
 135   public:  

 282     void gather(int result_cb, Fermion_t psi, int dag);
 283     void gather(int mu, int result_cb, Fermion_t psi, int dag); 

1018 };

From my understanding, the class bfmcommQMP should have inherited the non-virtual function gather from bfmbase. Apparently that is not the case, otherwise Clang would not complain about that.

What am I missing here? Why is the function gather not available inside the bfmcommQMP::comm_start member function?

vsoftco
  • 55,410
  • 12
  • 139
  • 252
Martin Ueding
  • 8,245
  • 6
  • 46
  • 92

1 Answers1

3

The problem is that your derived class is a dependent name. You need to qualify the call to gather() in the base class with this->gather() instead, otherwise the compiler does not resolve gather() from the base class. To simplify,

template<class T> struct Base
{
    void f();
};

template<class T> struct Derived: Base<T> // dependent name
{
    void foo()
    {
        this->f(); // won't compile without this->
    }
};

An alternative is to do

using Base::f;

in the derived Derived::foo() or qualify the call like

Base::f();

Related: Why do I have to access template base class members through the this pointer?

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • This also explains why every other invocation in that method is prefixed with `this->`! Now I get some other compilation error, this one seems solved. Thank you very much, I was looking everywhere else and would not have ever thought that something like this might be the cause. – Martin Ueding Nov 24 '16 at 21:43
  • You're welcome. [C++ Templates: The Complete Guide](https://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842) is, imo, the best book on templates, tells you everything you ever wondered about templates. Old (2002) but still very relevant. The authors are working on an update to modern C++ (C++11 and later). – vsoftco Nov 24 '16 at 21:46