C++ 初始化为相同的变量

C++ 初始化为相同的变量,c++,C++,我刚刚在单元测试代码中发现这是一个错误类型: Binding binding(x, y, z); Binding moved(std::move(moved)); // Should be `std::move(binding)` 为什么这是有效代码?这里发生了什么?这不是一个错误吗 #include <string> #include <iostream> int main() { std::string x(std::move(x)); std:

我刚刚在单元测试代码中发现这是一个错误类型:

Binding binding(x, y, z);
Binding moved(std::move(moved));  // Should be `std::move(binding)`
为什么这是有效代码?这里发生了什么?这不是一个错误吗

#include <string>
#include <iostream>

int main() {
    std::string x(std::move(x));
    std::cout << '"' << x << '"' << std::endl;
}
#包括
#包括
int main(){
std::stringx(std::move(x));
标准::cout
为什么这是有效代码

它不是。它在语法上是有效的,但有未定义的行为(假设构造函数使用它的参数)

这里发生了什么

假设移动构造函数的行为符合预期,
moved
使用其自身未初始化的值进行初始化。使用未初始化的值会产生未定义的行为

这不是一个错误吗

#include <string>
#include <iostream>

int main() {
    std::string x(std::move(x));
    std::cout << '"' << x << '"' << std::endl;
}
可能是,但不是。您可以在其初始值设定器中访问变量的名称,只要不使用该值,该名称就是合法的。例如:

void * p = &p;
定义良好,初始化指向自身的指针

由于它是通过引用传递给用户声明的构造函数的,因此编译器无法判断该值是否可以使用,因此无法发出警告。

它是有效的*(取决于
绑定的定义
),因为声明的名称从声明的时候就可以立即知道

例如

是相同一般原则的一个示例,并且

Node head = {&head, 0};
是使用(或滥用)该思想的变量声明的更直接的例子



*如果代码调用通常的移动构造函数,该构造函数试图从未初始化的对象移动,那么这是未定义的行为,从这个意义上说是无效的。

re“
moved
使用其自身未初始化的值进行初始化”,这是最有可能发生的事情,对班级一无所知,但这确实取决于班级。此外,问题不太可能与这方面有关。@Cheers Sandhth.-Alf:的确,我在这里做了一点假设。问题链接中的示例(使用
std::string
而不是未知的
绑定
)当然可以。谢谢。这个例子是C语言中的一个很好的例子,我能理解它是如何映射到汇编的。我想在这个例子中,
std::string
是用一个指向未初始化堆栈存储的指针调用的move构造函数。噢,我没有看到
std::string
例子。但是现在我看得更近了…这个例子是已知的UB,因为
std::string
有一个普通的移动构造函数。