为什么复制分配会导致 GCC 发出 -Wvirtual-move-assign 警告?
Why does copy assignment cause GCC to give a -Wvirtual-move-assign warning?
如果为 B 的实例调用移动分配,则以下 class 层次结构将在 GCC 中引起 [-Wvirtual-move-assign] 警告。
struct A {
std::vector<int> v;
};
struct B : public virtual A {};
以下场景确实会导致出现警告
/*** SCENARIO 1 ***/
class C {
B a;
public:
void foo(B& b) {
b = a; // warning
// or
a = b; // warning
}
};
/*** SCENARIO 2 ***/
void foo(const B& a, B& b) {
b = a; // warning
}
int main() {
/*** SCENARIO 3 ***/
B b;
std::vector<B> v1;
v1.push_back(b); // warning
/*** SCENARIO 4 ***/
B b1;
B b2;
b1 = b2; // warning
/*** SCENARIO 5 ***/
B b3;
b3 = B(); // warning
}
即使稍后再次使用分配的对象,警告仍然会出现。除了场景 5 涉及右侧的右值并因此涉及移动赋值外,我希望(实际上我希望)在这些场景中发生复制赋值而不是移动赋值。如果是这样,那么为什么会出现此警告?表达式中的某处是否实际发生了移动赋值?
你好像误报了。 Why does gcc warn about calling a non-trivial move assignment operator with std::tuple and virtual inheritance? 的答案表明 gcc 比实际需要更频繁地发出此警告,而 clang 则不会。所以我加强了你的例子(就像在那个答案中所做的那样)并将它交给了 clang。
struct A {
std::vector<int> v;
};
struct AA : public virtual A {};
struct AB : public virtual A {};
struct B : public AA, AB {};
使用此设置,clang 仅针对 b3 = B();
行发出警告(场景 5)。它接受其他情况,表明 gcc 只是偏执。 (要么是 gcc 发出误报,要么是 clang 有错误。不过,您的分析似乎是正确的,所以可能是前者。)
如果为 B 的实例调用移动分配,则以下 class 层次结构将在 GCC 中引起 [-Wvirtual-move-assign] 警告。
struct A {
std::vector<int> v;
};
struct B : public virtual A {};
以下场景确实会导致出现警告
/*** SCENARIO 1 ***/
class C {
B a;
public:
void foo(B& b) {
b = a; // warning
// or
a = b; // warning
}
};
/*** SCENARIO 2 ***/
void foo(const B& a, B& b) {
b = a; // warning
}
int main() {
/*** SCENARIO 3 ***/
B b;
std::vector<B> v1;
v1.push_back(b); // warning
/*** SCENARIO 4 ***/
B b1;
B b2;
b1 = b2; // warning
/*** SCENARIO 5 ***/
B b3;
b3 = B(); // warning
}
即使稍后再次使用分配的对象,警告仍然会出现。除了场景 5 涉及右侧的右值并因此涉及移动赋值外,我希望(实际上我希望)在这些场景中发生复制赋值而不是移动赋值。如果是这样,那么为什么会出现此警告?表达式中的某处是否实际发生了移动赋值?
你好像误报了。 Why does gcc warn about calling a non-trivial move assignment operator with std::tuple and virtual inheritance? 的答案表明 gcc 比实际需要更频繁地发出此警告,而 clang 则不会。所以我加强了你的例子(就像在那个答案中所做的那样)并将它交给了 clang。
struct A {
std::vector<int> v;
};
struct AA : public virtual A {};
struct AB : public virtual A {};
struct B : public AA, AB {};
使用此设置,clang 仅针对 b3 = B();
行发出警告(场景 5)。它接受其他情况,表明 gcc 只是偏执。 (要么是 gcc 发出误报,要么是 clang 有错误。不过,您的分析似乎是正确的,所以可能是前者。)