Допустим, у меня есть следующий код:
#include <string>
#include <vector>
void foo(const std::vector<std::string> &vec)
{
/* произвольные операции с vec */
}
int main(int, char **)
{
for (unsigned i = 0; i < 1e6; ++i) {
foo({"foo" /* много букв */,
"bar" /* много букв */,
"baz" /* много букв */});
}
}
Под «много букв» понимаются строки, достаточно длинные для того, чтобы исключить small string optimization.
При выполнении данной программы я наблюдаю (clang 3.9.0, gcc 6.2.1, -std=с++14, наблюдения произведены с помощью valgrind), что вне зависимости от уровня оптимизации происходит 7 * 1e6 выделений памяти.
Отсюда возникает два вопроса:
- Почему аллокаций 7 миллионов, а не 4, учитывая move semantics и всё такое?
- Почему компилятор не может построить вектор со строками статически в .rodata, учитывая, что он передаётся по константной ссылке и не изменяется? Или какие-то свойства языка запрещают так делать?
Ответ на исходные вопросы получен, но возникает следующий: возможно ли сделать то же самое более оптимально, но не жертвуя читабельностью? Ответ получен.