[英]No initializer list vs. initializer list with empty pairs of parentheses
This is copy paste from this topic Initializing fields in constructor - initializer list vs constructor body 这是该主题的复制粘贴。 初始化构造函数中的字段-构造函数列表与构造函数主体
The author explains the following equivalence: 作者解释了以下等效性:
public : Thing(int _foo, int _bar){
member1 = _foo;
member2 = _bar;
}
is equivalent to
public : Thing(int _foo, int _bar) : member1(), member2(){
member1 = _foo;
member2 = _bar;
}
My understanding was that 我的理解是
How are these two equivalent? 这两个当量如何?
Your understanding is correct (assuming member1
and member2
have type `int). 您的理解是正确的(假设
member1
和member2
类型为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。仅当成员是具有用户定义的构造函数的类类型时,这两个公式才等效。
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. 总之,如果
member1
和member2
是非POD类型,则这两个代码段是等效的。
For certain POD types they are also equivalent in some sense . 对于某些POD类型,它们在某种意义上也是等效的。 Well, let's simplify a little more and assume
member1
and member2
have type int
. 好吧,让我们简化一些,并假设
member1
和member2
类型为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. 确实,在第二个片段中,无法观察到
member1
首先被初始化为0
的事实。 Only its assignment to _foo
is. 仅将其分配给
_foo
。 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
. 在GCC 4.8.1中使用选项
-O1
。 (The __atribute((noinline))__
prevents the compiler from inlining the function). (
__atribute((noinline))__
防止编译器内联函数)。 Then the generated assembly code is the same regardless whether the initialization line is present or not: 然后,无论是否存在初始化行,生成的汇编代码都是相同的:
-O1
with or without initialization -O1
有或没有初始化
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
进行编译时,汇编代码会根据是否存在初始化行而有所不同:
-O0
without initialization -O0
无需初始化
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 -O0
进行初始化
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. 请注意,带初始化的
-O0
比没有初始化的-O0
多了四行(上面标记)。 These extra lines initialize the two members to zero. 这些额外的行将两个成员初始化为零。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.