locked
static inline const in template RRS feed

  • Pergunta

  • It is VC++ MFC project in VS 219 Update 16.6.4 under Windows 10; 

    I know how to correct is but do not understand why it refuses to work.

    The code: 

    template <class H>
    struct Optimizer 
    {
      static inline vector<double> m_vMt = vector<double>(H::m_vWeights.size(), 0.0);
      static inline vector<double> m_vVt = vector<double>(H::m_vWeights.size(), 0.0);
    
      // Constants
      static inline const double m_b1 = 0.9;
      static inline const double m_b2 = 0.999;
      static inline double const m_eps = 1e-8;
      static inline size_t m_weightsSz = H::m_vWeights.size();
    
    
      static inline bool m_bStart = true;
      static inline double m_b1t = m_b1;
      static inline double m_b2t = m_b2;
    
      static inline void Fn(void)
      {
        m_bStart = false;
        for (size_t i = 0; i < m_weightsSz; i++)
        {
          double gradW = H::m_vWeights[i].m_d1Err;
          m_vMt[i] = m_b1 * m_vMt[i] + (1 - m_b1) * gradW;
          m_vVt[i] = m_b2 * m_vVt[i] + (1 - m_b2) * gradW * gradW;
    
          double mt_corr = m_vMt[i] / (1.0 - m_b1t);
          double vt_corr = m_vVt[i] / (1.0 - m_b2t);
    
          H::m_vWeights[i].m_d1Err = mt_corr / sqrt(vt_corr + m_eps); // No learning rate!
        }
    
        m_b1t *= m_b1;
        m_b2t *= m_b2;
      }
    
     };
    
    
      
    int main()
    {
    Optimizer<L1>::Fn();
    return 0;
    }
    
    Class L1 just has a member vector<double> m)vWeights

    In this code, m_b1t and n_b2t are initialized OK, but in Fn() debugger says that m_b1 and m_b2 are undefined, but the Compiler does not complain.

    But if I remove 'const' from, definitions like 

      static inline double m_b1 = 0.9;
      static inline double m_b2 = 0.999;
      static inline double const m_eps = 1e-8;
    

    all works just fine. Why?

    domingo, 19 de julho de 2020 22:35

Respostas

  • The const makes all the difference here.

    The const allows the compiler to do const folding and substitute references to the constant with immediate values instead. This is something that the compiler can do even when optimization is disabled.

    As an example:

    int wmain()
    {
    	const int a = 1;
    	int b = 2 + a;
    	int c = a;
    
    	return 0;
    }

    When compiled with /Od this produces the instruction sequence:

    const int a = 1;
    00007FF6E865171C  mov         dword ptr [a],1  
    int b = 2 + a;
    00007FF6E8651723  mov         dword ptr [b],3  
    int c = a;
    00007FF6E865172A  mov         dword ptr [c],1 

    Now, notice how b loads 3 directly and c loads 1 directly? If you removed the const from a then the compiler would use a to initialise the other variables. Of course this means that any memory associated with a would be optimized away under /O2.

    The debugger sees a memory location as the variable, so if the compiler has optimised away a variable then it will report that variable as being undefined because it doesn't exist it the debug information.

    So it shouldn't be too surprising for the debugger to show a variable as undefined. It's not as if it is undefined, this just means that the compiler optimised it away.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    • Marcado como Resposta Geoyar segunda-feira, 20 de julho de 2020 21:21
    segunda-feira, 20 de julho de 2020 07:45

Todas as Respostas

  • Hi, Geoyar

     

    Thank you for posting here.

     

    >> To solve static inline const in template

    Static const data members can be initialized directly in the class declaration only when the type is an integer type or an enumeration type. So, const could not modify double. You could use constexpr.

     

    Best regards,

    Barrnet


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    segunda-feira, 20 de julho de 2020 02:59
  • Probably it is a defect of Debugger that can be reported using Help menu.

    Try an alternative:

       static constexpr double m_b1 = 0.9;


    • Editado Viorel_MVP segunda-feira, 20 de julho de 2020 04:18
    segunda-feira, 20 de julho de 2020 04:15
  • The const makes all the difference here.

    The const allows the compiler to do const folding and substitute references to the constant with immediate values instead. This is something that the compiler can do even when optimization is disabled.

    As an example:

    int wmain()
    {
    	const int a = 1;
    	int b = 2 + a;
    	int c = a;
    
    	return 0;
    }

    When compiled with /Od this produces the instruction sequence:

    const int a = 1;
    00007FF6E865171C  mov         dword ptr [a],1  
    int b = 2 + a;
    00007FF6E8651723  mov         dword ptr [b],3  
    int c = a;
    00007FF6E865172A  mov         dword ptr [c],1 

    Now, notice how b loads 3 directly and c loads 1 directly? If you removed the const from a then the compiler would use a to initialise the other variables. Of course this means that any memory associated with a would be optimized away under /O2.

    The debugger sees a memory location as the variable, so if the compiler has optimised away a variable then it will report that variable as being undefined because it doesn't exist it the debug information.

    So it shouldn't be too surprising for the debugger to show a variable as undefined. It's not as if it is undefined, this just means that the compiler optimised it away.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    • Marcado como Resposta Geoyar segunda-feira, 20 de julho de 2020 21:21
    segunda-feira, 20 de julho de 2020 07:45
  • Thank for reply.

    I do know that static const class members could be initialized inside a class only if the types are int or enum, but I thought that inline changes it.

    Thank you again.

    segunda-feira, 20 de julho de 2020 21:26
  • Thank for replay. It works.
    segunda-feira, 20 de julho de 2020 21:27