Учитывая этот минимальный пример.
#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;
}
Я скомпилировал так:
g++ -std=c++98 -fno-elide-constructors -g -Wall str_return.cpp -o str_return
Мой г ++:
gcc version 4.7.1
Выход:
ptr: 0x804b04c
ptr: 0x804b04c
ptr: 0x804b07c
ptr: 0x804b07c
Почему указатели все еще равны?
Как я могу отключить это поведение?
Оптимизация возвращаемого значения влияет на локальный объект (s
в вашем str_return
функция). Вы никогда не используете это.
Сам строковый объект управляет динамической памятью и выбирает передать эту управляемую память следующей строке по возвращении. Что вы используете? тот управляемая память. Достаточно разумно, это не меняется.
Если вы действительно хотите увидеть эффект RVO, используйте локальный объект:
#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);
}
Возможно, вы не испытываете RVO. Наблюдаемое поведение может быть вызвано копией при оптимизации записи, используемой в реализации std::string
в GCC. Следовательно, конструктор копирования может фактически выполняться, но выделенный буфер не копируется.
Я не могу комментировать ответы, поэтому я поставлю свое уведомление здесь:
Если вы поставите конструктор, вызовите для вас строку s, и после этого вы вызовете str_return — адреса будут другими:
std::string s; // implicit constructor call
print_ptr( s );
s = str_return( "suffix" );
print_ptr( s );
std::cout << std::endl;
вывод будет:
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