简体   繁体   中英

What is the GCC option for disabling assignment operator optimizations

Let's start with this small example:

#include <vector>
#include <iostream>

using namespace std;

class A {
private:
    A& operator =(const A&);
};

int main(void) {
    vector<A> v;
    v = { A() };
    return 0;
}

Compilation of this code fails with the error message error: 'A& A::operator=(const A&)' is private . I have no idea why it needs the assignment operator so I tried to find out and changed the code to this:

#include <vector>
#include <iostream>

using namespace std;

class A {
public:
    A& operator =(const A& a) { cout << "operator=" << endl; return *this; }
};

int main(void) {
    vector<A> v;
    v = { A() };
    return 0;
}

Now the code compiles but when I execute it it does not output the debug message in the assignment operator implementation.

So the compiler wants the assignment operator but doesn't use it? I guess the compiler optimizes the assignment away somehow. Just like it optimizes the usage of move constructors (Which can be prevented with the option -no-elide-constructors ). Is there a compiler option which can prevent assignment optimimzations? Or is there a different explanation why the compiler wants to have an accessible assignment operator but doesn't use it during runtime?

In C++03, types being stored in a container need to be CopyConstructible and Assignable . In C++11, requirements are relaxed and applied to the operations performed on the container.

class A needs to be CopyConstructible and Assignable because being stored in vector That's why you need public operator=

int main(void) {
    vector<A> v;
    v = { A() }; // Copy Constructor

    A x;
    x = v[0]; // operator=
    return 0;
}

I little bit late but I still want to answer your question.

Your example shows a standard copy elision of C++. This is also discussed in another question .

That is, the compiler checks the correctness of your operation . You have to call a copy constructor right after default constructor to use vector and put your class inside, but call the default constructor only in order to improve performance.

C++ 11 solves the issue with the move constructor .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM