No initializer list vs. initializer list with empty pairs of parentheses

前端 未结 2 957
难免孤独
难免孤独 2021-01-22 08:45

This is copy paste from this topic Initializing fields in constructor - initializer list vs constructor body

The author explains the following equivalence:



        
相关标签:
2条回答
  • 2021-01-22 09:11

    Your understanding is correct (assuming member1 and member2 have type `int). The two forms are not equivalent; in the first, the members are not initialized at all, and cannot be used until they have been assigned. In the second case, the members will be initialized to 0. The two formulations are only equivalent if the members are class types with user defined constructors.

    0 讨论(0)
  • 2021-01-22 09:23

    You are right but the author is kind of right too!

    Your interpretation is completely correct as are the answers given by others. In summary the two snippets are equivalent if member1 and member2 are non-POD types.

    For certain POD types they are also equivalent in some sense. Well, let's simplify a little more and assume member1 and member2 have type int. Then, under the as-if-rule the complier is allowed to replace the second snippet with the first one. Indeed, in the second snippet the fact that member1 is first initlialized to 0 is not observable. Only its assignment to _foo is. This is the same reasoning that allows the compiler to replace these two lines

    int x = 0;
    x = 1;
    

    with this one

    int x = 1;
    

    For instance, I've compiled this code

    struct Thing {
    
        int member1, member2;
    
        __attribute__ ((noinline)) Thing(int _foo, int _bar)
            : member1(), member2() // initialization line
        {
            member1 = _foo;
            member2 = _bar;
        }
    };
    
    Thing dummy(255, 256);
    

    with GCC 4.8.1 using option -O1. (The __atribute((noinline))__ prevents the compiler from inlining the function). Then the generated assembly code is the same regardless whether the initialization line is present or not:

    -O1 with or without initialization

       0:   8b 44 24 04             mov    0x4(%esp),%eax
       4:   89 01                   mov    %eax,(%ecx)
       6:   8b 44 24 08             mov    0x8(%esp),%eax
       a:   89 41 04                mov    %eax,0x4(%ecx)
       d:   c2 08 00                ret    $0x8
    

    On the other hand, when compiled with -O0 the assembly code is different depending on whether the initialization line is present or not:

    -O0 without initialization

       0:   55                      push   %ebp
       1:   89 e5                   mov    %esp,%ebp
       3:   83 ec 04                sub    $0x4,%esp
       6:   89 4d fc                mov    %ecx,-0x4(%ebp)
       9:   8b 45 fc                mov    -0x4(%ebp),%eax
       c:   8b 55 08                mov    0x8(%ebp),%edx
       f:   89 10                   mov    %edx,(%eax)
      11:   8b 45 fc                mov    -0x4(%ebp),%eax
      14:   8b 55 0c                mov    0xc(%ebp),%edx
      17:   89 50 04                mov    %edx,0x4(%eax)
      1a:   c9                      leave  
      1b:   c2 08 00                ret    $0x8
      1e:   90                      nop
      1f:   90                      nop
    

    -O0 with initialization

       0:   55                      push   %ebp
       1:   89 e5                   mov    %esp,%ebp
       3:   83 ec 04                sub    $0x4,%esp
       6:   89 4d fc                mov    %ecx,-0x4(%ebp)
       9:   8b 45 fc                mov    -0x4(%ebp),%eax   ; extra line #1
       c:   c7 00 00 00 00 00       movl   $0x0,(%eax)       ; extra line #2
      12:   8b 45 fc                mov    -0x4(%ebp),%eax   ; extra line #3
      15:   c7 40 04 00 00 00 00    movl   $0x0,0x4(%eax)    ; extra line #4
      1c:   8b 45 fc                mov    -0x4(%ebp),%eax
      1f:   8b 55 08                mov    0x8(%ebp),%edx
      22:   89 10                   mov    %edx,(%eax)
      24:   8b 45 fc                mov    -0x4(%ebp),%eax
      27:   8b 55 0c                mov    0xc(%ebp),%edx
      2a:   89 50 04                mov    %edx,0x4(%eax)
      2d:   c9                      leave  
      2e:   c2 08 00                ret    $0x8
      31:   90                      nop
      32:   90                      nop
      33:   90                      nop
    

    Notice that -O0 with initialization has four extra lines (marked above) than -O0 without initialization. These extra lines initialize the two members to zero.

    0 讨论(0)
提交回复
热议问题