请考虑以下代码,在此代码中我们根据 D
的另一部分初始化了其一部分:
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
上面的程序是否定义良好?我们可以安全地使用同一数组的一部分来初始化另一部分吗?
请考虑以下代码,在此代码中我们根据 D
的另一部分初始化了其一部分:
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
上面的程序是否定义良好?我们可以安全地使用同一数组的一部分来初始化另一部分吗?
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
使用int{}
表达式的值(即0
)初始化ss.a
为1
,ss.b
为"asdf"
,并将ss.d
初始化为ss.b[ss.a]
的值(即's'
),其中ss.c
被初始化为一个表达式的值。
数组成员可以进行自引用初始化吗?
是的。
struct c {
int a[3];
c() : a{4, a[0], 3} {} // a[0] is initialized to 4.
// a[1] is initialized to whatever a[0] is. (4)
// a[2] is initialized to 3.
};
但是请考虑这个例子:
struct c {
int a[3];
c() : a{a[1], 4, a[1]} {} // a[0] is initialized to whatever a[1] is.(Garbage value)
// a[1] is initialized to 4.
// a[2] is initialized to what a[1] is now (4).
};
这里,数组a
中的第一个元素将是a[1]
中的任何值,
通常情况下将是垃圾值。第二个元素被初始化为4
,
第三个元素被初始化为a[1]
中现在的值4
。
此外,当您未在{}
内列出数组中的所有元素时,
未列出的元素将进行默认初始化:
struct c {
int a[5]; // notice the size
c() : a{a[1], 2, 3, 4}{} // a[0] will get value that is in a[1]
// but since a[1] has garbage value,
// it will be default initialized to 0.
// a[1] = 2
// a[2] = 3
// a[3] = 4
// a[4] is not listed and will get 0.
};
然而,列出已初始化的元素将会给你想要的值。
以上面的例子为例:
struct c {
int a[5];
c() : a{1, a[0], 3, 4}{} // a[0] = 1
// a[1] = 1
// a[2] = 3
// a[3] = 4
// a[4] is not listed and will get 0.
};
D{rand(),D[0]}
,因为当构造函数运行时,第一个 rand() 不一定会先执行,然后才是 D[0],这完全取决于编译器,D[0] 可能会先执行,在这种情况下 d[1] 将包含垃圾值。它完全取决于编译器,它可以先编译第二个参数,然后再编译第一个参数,或者反之,执行此语句可能导致未知的行为。D[0]
之前必须调用 rand()
,所以你是错误的:il 不是函数调用,如果它是函数调用,你就是正确的。不太清楚 D[0]
是否在读取之前被初始化。 - Yakk - Adam Nevraumont