Now that it's answered: Don't bother reading this question, it's a bit lengthy and probably not worth your time. There were bugs in my code, and that was the reason why the move constructor wasn't called. Check the answers for details. Keep in mind that RVO and NRVO (Named Return Value Optimization) might account for the calls not happening as you expect.

---

I expect the move ctor to be called for this line, but the copy ctor is called instead:

```
Ding d3 = d1 + d2;

```

The Ding class has a user-defined move ctor and on operator+ overload. The reason I expect the move ctor to be called is that the operator+ returns a temporary object, an rvalue reference, so the move optimization could happen.

Everything I'm writing here might be wrong as I'm a C++ beginner. Here's the code:

```
// Copied and modified code from here: https://stackoverflow.com/a/3109981
#include <iostream>
#include <cstring>

struct Ding {
    char* data;

    Ding(const char* p) {
        std::cout << " ctor for: " << p << "\n";
        size_t size = strlen(p) + 1;
        data = new char[size];
        memcpy(data, p, size);
    }

    ~Ding() {
        std::cout << " dtor for: " << data << "\n";
        delete[] data;
    }

    Ding(const Ding& that) {
        std::cout << " copy for: " << that.data << "\n";
        size_t size = strlen(that.data) + 1;
        data = new char[size];
        memcpy(data, that.data, size);
    }

    Ding(Ding&& that) {
        std::cout << " MOVE for: " << that.data << "\n";
        data = that.data;
        that.data = nullptr;
    }

    Ding& operator=(Ding that) {
        std::cout << " assignment: " << that.data << "\n";
        std::swap(data, that.data);
        return *this;
    }

    Ding& operator+(const Ding that) const {
        std::cout << " plus for: " << that.data << "\n";
        size_t len_this = strlen(this->data);
        size_t len_that = strlen(that.data);
        char * tmp = new char[len_this + len_that + 1];
        memcpy( tmp,          this->data, len_this);
        memcpy(&tmp[len_this], that.data, len_that + 1);
        Ding * neu = new Ding(tmp);
        return *neu;
    }
};

void print(Ding d) {
    std::cout << "  (print): " << d.data << std::endl;
}

int main(void) {
    std::cout << "putting a Ding on the stack\n";
    Ding d1("jajaja");
    std::cout << "calling print routine\n";
    print(d1);
    std::cout << "putting a second Ding on the stack\n";
    Ding d2("nein");
//  std::cout << "calling print routine\n";
//  print(d2);
    std::cout << "Putting a third Ding on the stack, init from + op ...\n";
    std::cout << "... so expecting so see MOVE ctor used ...\n";
    Ding d3 = d1 + d2;
//  std::cout << "calling print routine\n";
//  print(d3);
    std::cout << "End of main, dtors being called ...\n";
}

```

The compiler invocations (on Win7) for VC2010 Express and MinGW (GCC 4.6) are as follows:

```
cl /nologo /W4 /EHsc /MD move-sem.cpp
g++ -std=c++0x move-sem.cpp -o move-gcc.exe

```

Both binaries produce the same output (sans order of destruction at end of program):

```
putting a Ding on the stack
 ctor for: jajaja
calling print routine
 copy for: jajaja
  (print): jajaja
 dtor for: jajaja
putting a second Ding on the stack
 ctor for: nein
Putting a third Ding on the stack, init from + op ...
... so expecting so see MOVE ctor used ...
 copy for: nein
 plus for: nein
 ctor for: jajajanein
 dtor for: nein
 copy for: jajajanein
End of main, dtors being called ...
 dtor for: jajajanein
 dtor for: nein
 dtor for: jajaja

```

To recall what the question was after this long text: Why isn't the move constructor called for `Ding d3 = d1 + d2;`?

I'm aware that there are other questions as to why move ctors aren't getting called but I cannot map their answers to this case.

* [Why doesn't this C++0x code call the move constructor?](https://stackoverflow.com/q/1046801/269126)
* [Why is this code trying to call the copy constructor?](https://stackoverflow.com/q/8991874/269126)
* [Move constructor is not getting called in C++0x](https://stackoverflow.com/q/7645985/269126)

Update
------

I changed the program as follows as per David Rodriguez' comments:

```
--- move-sem.cpp.orig   2012-03-17 17:00:56.901570900 +0100
+++ move-sem.cpp        2012-03-17 17:01:14.016549800 +0100
@@ -36,15 +36,14 @@
                return *this;
        }

-       Ding& operator+(const Ding that) const {
+       Ding operator+(const Ding that) const {
                std::cout << " plus for: " << that.data << "\n";
                size_t len_this = strlen(this->data);
                size_t len_that = strlen(that.data);
                char * tmp = new char[len_this + len_that + 1];
                memcpy( tmp,          this->data, len_this);
                memcpy(&tmp[len_this], that.data, len_that + 1);
-               Ding * neu = new Ding(tmp);
-               return *neu;
+               return tmp;
        }
 };

```

I then recompiled the program using the compiler invocations mentioned above and got an output where one copy (`copy for: jajajanein`) was removed. I then tried the following line:

```
g++ -std=c++0x -fno-elide-constructors move-sem.cpp -o move-gcc.exe

```

And tata! Now I'm seeing the move ctor at work! ... But I think there's another error now, the output of that new `move-gcc.exe` doesn't list the dtor invocations any more:

```
putting a Ding on the stack
 ctor for: jajaja
calling print routine
 copy for: jajaja
  (print): jajaja
 dtor for: jajaja
putting a second Ding on the stack
 ctor for: nein
Putting a third Ding on the stack, init from + op ...
... so expecting so see MOVE ctor used ...
 copy for: nein
 plus for: nein
 ctor for: jajajanein
 MOVE for: jajajanein
 dtor for:

```

Second Update
-------------

I replaced the bad `operator+` with the following (possibly equally bad) code:

```
Ding& operator+=(const Ding & rhs) {
    std::cout << " op+= for: " << data << " and " << rhs.data << "\n";
    size_t len_this = strlen(this->data);
    size_t len_that = strlen(rhs.data);
    char * buf = new char[len_this + len_that + 1];
    memcpy( buf,         this->data, len_this);
    memcpy(&buf[len_this], rhs.data, len_that + 1);
    delete[] data;
    data = buf;
    return *this;
}

Ding operator+(const Ding & rhs) const {
    Ding temp(*this);
    temp += rhs;
    return temp;
}

```

I also removed the following line from the destructor, and it stopped the program from terminating abnormally:

```
std::cout << " dtor for: " << data << "\n";

```

The move constructor is now being called when compiling with MSVC and with `g++ -std=c++0x -fno-elide-constructors`.