none
How are fields initialized in CLR wrt constructors RRS feed

  • Question

  • Given the following class:

     

    public class Class1

    {

        private string m_one = String.Empty;

        private string m_two;

     

        public Class1()

        {

            m_two = String.Empty;

        }

     

        public Class1(string one)

        {

            m_one = one;

        }

    }

     

    Can someone clarify  which of the following happens to the m_one field during construction?

    1)      Class memory is zeroed and m_one is assigned string.empty

    2)      m_one is assigned null first (i.e. IL is generated to assign the field) and then assigned string.empty

    3)      m_one is directly assigned to string.Empty, avoiding being zero’ed or nulled first.

     

    Basically, is it an optimization to assign in the field and not in the constructor?

     

    Thanks

     


    Posting is provided "AS IS" with no warranties, and confers no rights.
    Friday, August 5, 2011 10:42 PM

Answers

  • Field assignments are actually moved to the constructors so the above code results in:

    public class Class1 {
      private string m_one;
      private string m_two;
     
      public Class1() {
        m_one = String.Empty;
        m_two = String.Empty;
      }
     
      public Class1(string one) {
        m_one = String.Empty;
        m_one = one;
      }
    }
    
    

    So:

    1) Yes. Zeroing out is always done (but not by the ctor) and m_one is always assigned String.Empty first.

    2) Nope, there's no specific assignment of null. Zeroing out does the job.

    3) Nope, see 1), zeroing out is always done.

    Basically there's no optimization. In fact, in the particular case of Class1(string one) ctor, it is a de-optimization because m_one is assigned twice.

    • Marked as answer by Paul Zhou Monday, August 15, 2011 6:13 AM
    Friday, August 5, 2011 11:12 PM
    Moderator
  • 1) Yes. Zeroing out is always done (but not by the ctor) and m_one is always assigned String.Empty first.


    Actually it is initialized to null during initialization (not String.Empty (which is equal to "")) first , then String.Empty and then m_one

    As correctly pointed , the field initialization is translated to member assignment inside constructor. So optimiziation is not  earned.

    There's a small catch : Field assignment are moved to ctor correct, but field assignment is done before the base class ctor is called, so the translated code will be like

    `assign m_one to String.Empty`

    `call base class ctor`

    `assign m_one to one`

     

     

    Best

    Ray


    • Marked as answer by Paul Zhou Monday, August 15, 2011 6:14 AM
    Monday, August 8, 2011 2:01 PM

All replies

  • Field assignments are actually moved to the constructors so the above code results in:

    public class Class1 {
      private string m_one;
      private string m_two;
     
      public Class1() {
        m_one = String.Empty;
        m_two = String.Empty;
      }
     
      public Class1(string one) {
        m_one = String.Empty;
        m_one = one;
      }
    }
    
    

    So:

    1) Yes. Zeroing out is always done (but not by the ctor) and m_one is always assigned String.Empty first.

    2) Nope, there's no specific assignment of null. Zeroing out does the job.

    3) Nope, see 1), zeroing out is always done.

    Basically there's no optimization. In fact, in the particular case of Class1(string one) ctor, it is a de-optimization because m_one is assigned twice.

    • Marked as answer by Paul Zhou Monday, August 15, 2011 6:13 AM
    Friday, August 5, 2011 11:12 PM
    Moderator
  • 1) Yes. Zeroing out is always done (but not by the ctor) and m_one is always assigned String.Empty first.


    Actually it is initialized to null during initialization (not String.Empty (which is equal to "")) first , then String.Empty and then m_one

    As correctly pointed , the field initialization is translated to member assignment inside constructor. So optimiziation is not  earned.

    There's a small catch : Field assignment are moved to ctor correct, but field assignment is done before the base class ctor is called, so the translated code will be like

    `assign m_one to String.Empty`

    `call base class ctor`

    `assign m_one to one`

     

     

    Best

    Ray


    • Marked as answer by Paul Zhou Monday, August 15, 2011 6:14 AM
    Monday, August 8, 2011 2:01 PM