Question

Given this minimal example.

#include <iostream>
#include <string>

void print_ptr(const std::string& s)
{
    const char* data = s.data();
    std::cout << "ptr: " << (void*)data << std::endl;
}

std::string str_return(const char* suffix)
{
    std::string s("prefix");
    s += " ";
    s += suffix;
    print_ptr(s);
    return s;
}

int main()
{
    std::string s = str_return("suffix"), t;
    print_ptr(s);
    t = str_return("suffix2");
    print_ptr(t);
    return 0;
}

I compiled like this:

g++ -std=c++98 -fno-elide-constructors -g -Wall  str_return.cpp -o str_return

My g++:

gcc version 4.7.1

The output:

ptr: 0x804b04c
ptr: 0x804b04c
ptr: 0x804b07c
ptr: 0x804b07c

Why are the pointers still equal?

  • It should not be return value optimization - I switched it off
  • It should not be move constructors since I took a really old standard of c++

How can I disable this behaviour?

Was it helpful?

Solution

Return value optimization affects the local object (s in your str_return function). You never instrument that.

The string object itself manages dynamic memory and chooses to hand that managed memory over to the next string upon return. What you're instrumenting is that managed memory. Sensibly enough, that doesn't change.

If you really want to see the effect of RVO, instrument the local object:

#include <iostream>
#include <string>

void print_ptr(const std::string& s)
{
    std::cout << "ptr: " << static_cast<const void *>(&s) << std::endl;
}

std::string str_return(const char* suffix)
{
    std::string s("prefix");
    s += " ";
    s += suffix;
    print_ptr(s);
    return s;
}

int main()
{
    std::string s = str_return("suffix");
    print_ptr(s);
    std::string t = str_return("suffix2");
    print_ptr(t);
}

OTHER TIPS

You may not be experiencing RVO. The observed behavior may be caused by the copy on write optimization used in the implementation of std::string in GCC. Therefore a copy constructor may actually run, but the allocated buffer is not copied.

I cant comment answers, so I will put my notice here: If you put constructor call for you string s, and after that you call str_return - addresses will be different:

std::string s; // implicit constructor call
print_ptr( s );
s  = str_return( "suffix" );
print_ptr( s );
std::cout << std::endl;

the output will be:

ptr: 0x28fec4  // for the original s;
ptr: 0x28fec8  // for local variable in function str_return
ptr: 0x28fec4  // the address of s after call str_return didn't change
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top