- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑以下简单代码:
struct Base
{
Base() = default;
Base(const Base&);
Base(Base&&);
};
struct Derived : Base { };
Base foo()
{
Derived derived;
return derived;
}
clang 8.0.0 gives a warning -Wreturn-std-move
在上面:
prog.cc:21:10: warning: local variable 'derived' will be copied despite being returned by name [-Wreturn-std-move]
return derived;
^~~~~~~
prog.cc:21:10: note: call 'std::move' explicitly to avoid copying
return derived;
^~~~~~~
std::move(derived)
但是如果在这里调用 std::move
代码的行为可能会改变,因为 Derived
对象的 Base
子对象将是在调用 Derived
对象的析构函数之前 move ,最后一个代码的行为会有所不同。
例如看the code (compiled with the -Wno-return-std-move
flag) :
#include <iostream>
#include <iomanip>
struct Base
{
bool flag{false};
Base()
{
std::cout << "Base construction" << std::endl;
}
Base(const bool flag) : flag{flag}
{
}
Base(const Base&)
{
std::cout << "Base copy" << std::endl;
}
Base(Base&& otherBase)
: flag{otherBase.flag}
{
std::cout << "Base move" << std::endl;
otherBase.flag = false;
}
~Base()
{
std::cout << "Base destruction" << std::endl;
}
};
struct Derived : Base
{
Derived()
{
std::cout << "Derived construction" << std::endl;
}
Derived(const bool flag) : Base{flag}
{
}
Derived(const Derived&):Base()
{
std::cout << "Derived copy" << std::endl;
}
Derived(Derived&&)
{
std::cout << "Derived move" << std::endl;
}
~Derived()
{
std::cout << "Derived destruction" << std::endl;
std::cout << "Flag: " << flag << std::endl;
}
};
Base foo_copy()
{
std::cout << "foo_copy" << std::endl;
Derived derived{true};
return derived;
}
Base foo_move()
{
std::cout << "foo_move" << std::endl;
Derived derived{true};
return std::move(derived);
}
int main()
{
std::cout << std::boolalpha;
(void)foo_copy();
std::cout << std::endl;
(void)foo_move();
}
它的输出:
foo_copy
Base copy
Derived destruction
Flag: true
Base destruction
Base destruction
foo_move
Base move
Derived destruction
Flag: false
Base destruction
Base destruction
最佳答案
Clang 的警告当然是正确的。由于 derived
的类型不同于函数的返回类型,因此在语句 return derived;
中,编译器必须将 derived
视为左值, 并且会出现一个拷贝。并且可以通过编写 return std::move(derived);
来避免此拷贝,使其显式成为右值。警告不会告诉您是否应该这样做。它只是告诉您您正在做的事情的后果,以及使用 std::move
的后果,并让您自己下定决心。
您担心 Derived
的析构函数可能会在 Base
状态被 move 后访问它,这可能会导致错误。如果确实出现此类错误,那是因为 Derived
的作者犯了错误,而不是因为用户不应该 move Base
子对象。此类错误可以通过与其他错误相同的方式被发现,并报告给 Derived
的作者。
我为什么这么说?因为当作者使 Base
成为 Derived
的 public 基类时,他们向用户 promise 他们有权使用完整的 Base
接口(interface),每当与 Derived
对象交互时,包括从它 move 。因此,Derived
的所有成员函数必须准备好处理这样一个事实,即用户可能以 Base
的任何方式修改了 Base
子对象的接口(interface)允许。如果不需要,则可以将 Base
设为 Derived
的私有(private)基类,或私有(private)数据成员,而不是公共(public)基类。
关于c++ - 对于同一层次结构中的对象,-Wreturn-std-move clang 警告是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55924330/
好的,我有一个 C 语言的代码。它是零和十字。但我不知道我的'sprawdzenie'(检查)。IDE 向我发送控制可能会到达非空函数 [-Wreturn-type] 的结尾。我不知道出了什么问题,但
我在功能方面遇到了一个小问题。我相信这可能是因为我没有正确使用它们。我的代码如下: int duration(string fraction) { // X part of the fract
我写了一段代码: int gnrt(vector vect, int n) { std::vector :: iterator it; it = find(vect.begin()
我正在尝试编译 Model 5.0在 OS X 10.8.3 下编译时我收到很多警告和错误。其中一些错误类似于 xwin.c:31523:2: error: non-void function 'sc
我正在尝试创建一个简短的线性搜索算法,但不断收到错误消息控制可能到达非空函数结尾-wreturn-type。我知道该错误与将返回值放在循环之外有关,但是如何从循环中获取返回值呢? 这是代码: bool
这个问题在这里已经有了答案: Returning array declared in function returns address of local variable in C? (4 个答案)
我正在开发一个简单的程序,它将获取给定变量的内存地址,最多 64 位(unsigned long)。目前这是我的代码,但出于某种原因,编译器向我发出警告,说我的方法正在返回局部变量的地址,而这正是我想
根据 GCC 手册,-Wreturn-type 选项通过 -Wall 启用。但是,我找不到在保持 -Wall 的其余部分启用的同时禁用它的正确方法。 考虑这段代码: func() {} 如果在没有警告
我在 gcc ,它给了我一个警告,我忘记了函数中的返回值 Wreturn-type . 但是,我不希望它是一个警告,我希望它是一个实际的编译器错误。有没有办法在 Wreturn-type 时停止编译是
我有这个,当我尝试编译时,终端给我错误;有人可以帮助我吗? int e=0; float func(float x, float y, float z) { e++; if((x*
我在一个编译器上编写了一个调度程序。当我在 Debian 9 Linux 上编译时,一切正常,但是当我尝试在运行 macOS 的 Mac 上编译时,它会显示很多警告和此错误: error: non-v
考虑以下简单代码: struct Base { Base() = default; Base(const Base&); Base(Base&&); }; struct
如果我有一个基于切换 enum class 返回的函数, gcc 发出 warning: control reaches end of non-void function [-Wreturn-type
我是一名开始学习 C 的 Linux 用户,我正在尝试编译我输入的源代码: #include main() { float c,d; c = 10215.3;
Visual Studio 是否有相当于 GCC 的 -Wreturn-type 的警告(或警告)? ? 更具体地说,我正在寻找一个 Visual Studio 警告(或多个警告),它会针对返回类型不
C语言编程 代码: struct battleship makeShip (int size, int pos) { int i, j; int* body; body = (
我有一段代码: int check(int d, char arr[9][9], int rep_arr[45][3]) { int p = findProb(d, arr, rep_arr,
我有一段代码: int check(int d, char arr[9][9], int rep_arr[45][3]) { int p = findProb(d, arr, rep_arr,
错误信息在标题中。有谁知道怎么了?我想清除这个警告。我一无所知。 const std::string loadShaderFromFile(std::string shaderFilePath)
我在编译时遇到这个错误,并在此处检查了其他问题,但没有进一步的进展: funciones.c: In function ‘Lyapunov’: ../funciones.c:55:2: warning
我是一名优秀的程序员,十分优秀!