Я хочу понять последствия оптимизации хвостового вызова в C ++. Рассмотрим следующий фрагмент кода:
#include <iostream>
#include <string>
size_t mystrlen(const char* input, size_t size = 0){
if(!*input){
return size;
}else{
std::string str(input+1);
return mystrlen(str.c_str(),size + 1);
}
}
int main(void){
std::cout << mystrlen("Foo") << std::endl; //3
}
mystrlen
является (бесполезной) функцией, которая вычисляет длину предоставленной строки C. Рассмотрим остальную ветку: новый std::string
экземпляр создан, и его внутренний буфер используется в качестве входных данных для следующего вызова. Если произойдет оптимизация хвостового вызова и не будут созданы новые кадры стека, это не приведет к ошибке, потому что локальная переменная str
будет уничтожен до следующего звонка?
Оптимизация вызовов хвоста в C ++ подпадает под свободу оптимизации «как будто», которую имеют компиляторы C ++.
Запрет на компилятор с очень подробным знанием std::string
на высоком уровне то, что вы сделали, заблокирует оптимизацию хвостового вызова, поскольку нетривиальный деструктор должен вызываться после завершения рекурсивного вызова.
Во-первых, вы хотите избавиться от std::string
в этом случае:
size_t mystrlen(const char* input, size_t size = 0) {
if(!*input){
return size;
} else {
return mystrlen(input + 1, size + 1);
}
}
тогда вы можете видеть, что ваша оптимизация хвостового вызова будет просто:
size_t mystrlen(const char* input) {
size_t size = 0;
while (!*(input + size)) ++size;
return size;
}