С++ ссылка на статическую переменную
Я просто узнаю, что этот маленький кусочек кода С++ не дает мне тот же результат с clang++ и с g++:
#include <iostream>
#include <string>
using namespace std;
const string& createString(char c) {
static string s;
s="";
for(int i=0; i<10; ++i) {
s+=c;
}
return s;
}
int main() {
cout << createString('a') << ' ' << createString('z') << endl;
return 0;
}
С clang++ он пишет:
aaaaaaaaaa zzzzzzzzzz
как я хочу, но с g++ он пишет:
aaaaaaaaaa aaaaaaaaaa
Почему так? Соответствует ли стандарт реализации g++?
И что мне делать, если я хочу, чтобы функция возвращала временный "большой" тип по ссылке, как здесь, чтобы избежать ненужной копии?
спасибо, если вы можете помочь (и простите меня, если мой вопрос не ясен, английский не мой естественный язык).
Ответы
Ответ 1
И что мне делать, если я хочу, чтобы функция возвращала временную "большую" типа по ссылке, как здесь, чтобы избежать бесполезной копии?
Это не будет. RVO и NRVO могут тривиально позаботиться об этом. Кроме того, переместите семантику. Короче говоря, нет ничего проблематичного в возврате значения std::string
по значению.
Ответ 2
Да, обе реализации совместимы. Порядок оценки аргументов функции не указан.
Следовательно, createString('a')
и createString('z')
могут быть оценены в любом порядке. Кроме того, createString('z')
можно оценить до или после вычитания результата createString('a')
.
Поскольку функция является состоятельной и возвращает состояние по ссылке, оба выхода допустимы, как и zzzzzzzzzz zzzzzzzzzz
.
Наконец, стоит отметить, что наличие состояния static
будет серьезной головной болью в многопоточной среде.
Ответ 3
И что мне делать, если я хочу, чтобы функция возвращала временный "большой" тип по ссылке, как здесь, чтобы избежать ненужной копии?
Вызовите его только один раз для выражения. Например, это будет нормально работать:
std::cout << createString('a') << ' ';
std::cout << createString('z') << std::endl;