Учитывая такую настройку, где вызывается DoFooStuff ():
class Foo {
public:
void DoFooStuff(); // calls Bar::DoBarStuff()
}
class Bar {
public:
void DoBarStuff(); // Calls Bar::DoInternalBarStuff()
protected:
void DoInternalBarStuff();
}
Что может сделать возможным, чтобы моя трассировка стека могла показать именно это ?:
Type Function
void Bar::DoInternalBarStuff()
void Foo::DoFooStuff()
Единственная ссылка на DoInternalBarStuff () находится в DoBarStuff (). DoInternalBarStuff () утверждает в своей первой строке:
assert(false);
И это то место, откуда берется трассировка стека.
Является ли вызов Bar :: DoBarInternalStuff последним оператором в Bar :: DoBarStuff? Если это так, компилятор, скорее всего, заменил стековый фрейм Bar :: DoBarStuff на Bar :: DoBarInternalStuff, когда вызывался Bar :: DoBarInternalStuff.
Этот вид хвостовой вызов оптимизация довольно распространена в компиляторах C / C ++. Это уменьшает глубину стека, необходимую, когда рекурсивная функция может быть организована таким образом, что рекурсивный вызов является последним вызовом функции.
Получается, что компилятор выполняет автоматическое встраивание на определенных уровнях оптимизации. Учиться новым вещам каждый день. 🙂
Работает ли GCC inline C ++ без ключевого слова inline?
(Спасибо за полезные комментарии, которые показали мне это.)