相关疑难解决方法(0)

是否定义了在聚合初始化期间从后面的成员表达式引用早期成员的行为?

考虑以下:

struct mystruct
{
    int i;
    int j;
};

int main(int argc, char* argv[])
{
    mystruct foo{45, foo.i};   

    std::cout << foo.i << ", " << foo.j << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意foo.i在aggregate-initializer列表中的使用.

g++ 5.2.0 输出

45,45

这是明确定义的行为吗?是foo.i在这个聚集型初始化始终保证指存在创建结构的i元素(和&foo.i将指向内存地址,例如)?

如果我添加一个显式构造函数mystruct:

mystruct(int i, int j) : i(i), j(j) { }
Run Code Online (Sandbox Code Playgroud)

然后我收到以下警告:

main.cpp:15:20: warning: 'foo.a::i' is used uninitialized in this function [-Wuninitialized]
     a foo{45, foo.i};
                ^
main.cpp:19:34: warning: 'foo.a::i' is used uninitialized in this …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior language-lawyer c++11 c++14

35
推荐指数
2
解决办法
811
查看次数

(C/C++)数组初始化可以引用自身吗?

我想知道以下形式的初始化:

int  array[] = {
v - 1,
array[0] + 1
} ;
Run Code Online (Sandbox Code Playgroud)

在第二个元素的初始化中,使用第一个元素的值,但尚未初始化整个数组.这恰好用g ++编译,但我不确定这是否实际上是可移植的和定义良好的构造?

c++

30
推荐指数
2
解决办法
918
查看次数

在指定初始化程序中使用较早的成员

考虑以下代码:

struct Foo{
    std::string s1;
    std::string s2;
};

int main(){
    Foo f{.s1 = "s1", .s2 = f.s1 + "s2"};
    std::cout << "s1='" << f.s1 << "', s2='" << f.s2 << "'" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

特别注意 的初始化访问:s2的第一个成员。最新的 clang、gcc 和 MSVC 对代码很满意,并给出了天真的预期结果(它们打印)。观看Godbolt直播。f.s2 = f.s1 + "s2""s1='s1', s2='s1s2'"

问题:这合法吗?换句话说,标准是否保证在f.s1指定的初始化器被.s2评估之前被初始化?

相关:有一个类似的问题询问是否.s2 = .s1 + "s2"合法,这显然是不合法的,因为它无法编译。另外,P0328(根据答案)可能相关,但我看不到我的问题在那里得到解答。

c++ designated-initializer language-lawyer aggregate-initialization c++20

10
推荐指数
2
解决办法
455
查看次数

是否允许递归初始化数组?

我有以下代码片段:

int i[] = {42, i[0]};
Run Code Online (Sandbox Code Playgroud)

是允许这样的初始化还是导致未定义的行为?

三大编译器(GCC,铛,MSVC)给我42i[1].因此看起来合法,但我希望从这个案例的标准中看到一个引用.

c++ array-initialization language-lawyer

9
推荐指数
1
解决办法
238
查看次数