初始化为同一个变量

时间:2014-04-25 14:57:12

标签: 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::cout << '"' << x << '"' << std::endl;
}

Compiled with gcc 4.8

2 个答案:

答案 0 :(得分:5)

它是有效的 * (取决于Binding的定义),因为声明的名称是从声明点开始就知道的。

E.g。

struct Node { Node* next; int value; };

是同一个一般原则的一个例子,

Node head = {&head, 0};

是使用(或滥用)该想法的变量声明的更直接的例子。


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

答案 1 :(得分:4)

  

为什么这个有效的代码?

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

  

这里发生了什么?

假设移动构造函数的行为与预期的一样,moved使用自己的未初始化值进行初始化。使用未初始化的值会产生未定义的行为。

  

这不应该是一个错误吗?

也许,但事实并非如此。您可以在其初始化程序中访问变量的名称,只要您不使用该值,该名称就是合法的。例如,这个:

void * p = &p;

是明确定义的,初始化一个指向自身的指针。

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