-1

I am trying this code in Visual Studio 2015 v4.

using namespace std;

void * operator new(size_t size) {
    cout << "Creating new " << endl;
    void * p = malloc(size);
    return p;
}


class CTest {
private:
    string a;
    string b;
public:
    CTest( const string &&one , const string && two  ) :a(move(one)), b(move(two)) {}
};


int main() {
    CTest("one", "one" );
    return 0;   
}

This code outputs "Creating new" 4 times in Visual studio , which means it allocates memory 4 times. However following semantics it should only allocate twice ( creating 2 literals in data segment , creating one and two function argument = 2 allocs , and then moving their resource to a and b member variable )

Compiling this under g++ outputs "Creating new" twice, as it should.

Is there any settings i need to set in order for VS to follow moving semantics? It should be supported by default as far as i know.

Thanks for help.

Darlyn
  • 4,715
  • 12
  • 40
  • 90

2 Answers2

5

There are several issues here:

1) std::move does not move, especially if you pass by const &&. See answers here and here.

2) Every std::string implementation I am aware of uses small buffer optimization. Such implementations will never allocate when constructed with short strings (such as "one").

3) The standard library runtime is allowed to call operator new during static initialization, for instance to setup std::cout. The allocations you see are most likely not related to the string constructor or (lack of) move.

sbabbi
  • 11,070
  • 2
  • 29
  • 57
2

The arguments one and two are rvalue references to constant std::string objects. How can you move from a constant object?

Drop the const qualifier for the arguments. In most cases using the const qualifier doesn't make sense for rvalue references.

Or don't use either const nor rvalue references (and the compiler should create the correct code anyway).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621