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

前端 未结 2 988
难免孤独
难免孤独 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: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.

提交回复
热议问题