How does the compiler determine the needed stack size for a function with compiler generated temporaries?

浪尽此生 提交于 2019-12-05 17:38:14

The optimizing compiler is transforming your source code into some internal representation, and normalizing it.

With free software compilers (like GCC & Clang/LLVM), you are able to look into that internal representation (at the very least by patching the compiler code or running it in some debugger).

BTW, sometimes, temporary values do not even need any stack space, e.g. because they have been optimized, or because they can sit in registers. And quite often they would reuse some unneeded slot in the current call frame. Also (particularly in C++) a lot of (small) functions are inlined -like your getFoo probably is- (so they don't have any call frame themselves). Recent GCC are even sometimes able of tail-call optimizations (essentially, reusing the caller's call frame).

If you compile with GCC (i.e. g++) I would suggest to play with optimization options and developer options (and some others). Perhaps use also -Wstack-usage=48 (or some other value, in bytes per call frame) and/or -fstack-usage

First, if you can read assembler code, compile yourcode.cc with g++ -S -fverbose-asm -O yourcode.cc and look into the emitted yourcode.s

(don't forget to play with optimization flags, so replace -O with -O2 or -O3 ....)

Then, if you are more curious about how the compiler is optimizing, try g++ -O -fdump-tree-all -c yourcode.cc and you'll get a lot of so called "dump files" which contain a partial textual rendering of internal representations relevant to GCC.

If you are even more curious, look into my GCC MELT and notably its documentation page (which contains a lot of slides & references).

So for me it seems that the compiler reserves extra stack memory for every generated temporary object in the function.

Certainly not, in the general case (and of course assuming you enable some optimizations). And even if some space is reserved, it would be very quickly reused.

BTW: notice that the C++11 standard does not speak of stack. One could imagine some C++ program compiled without using any stack (e.g. a whole program optimization detecting a program without recursion whose stack space and layout could be optimized to avoid any stack. I don't know any such compiler, but I do know that compilers can be quite clever....)

Attempting to analyse how a compiler is going to treat a particular piece of code is getting progressively more difficult as optimisation strategies get more aggressive.

All a compiler has to do is implement the C++ standard and compile the code without introducing or cancelling any side-effects (with some exceptions such as return and named return value optimisation).

You can see from your code that, since cFoo is not a polymorphic type and has no member data, a compiler could optimise out the creation of an object altogether and call what are essentially therefore static functions directly. I'd imagine that even at the time of my writing, some compilers are already doing that. You could always check the output assembly to be sure.

Edit: The OP has now introduced class members. But since these are never initialised and are private, the compiler can remove them without thinking too hard about that. This answer therefore still applies.

Life time of a temporary object is up until the end of the full containing expression, see the paragraph "12.2 Temporary objects" of the Standard.

It is very unlikely that even with the lowest optimisation settings a compiler will not reuse the space after the end of life of a temporary object.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!