9 ms·
C++ Constructors, Memory, and Lifetimes
- zabzonk 5y agoThis is full of misunderstandings. When variables are allocated on the stack, the space for them with all compilers I have ever used (or written) is allocated on the stack once by adjusting the stack pointer - i.e. for all of the variables of the function. There is no pushing or popping - function variables have addresses on the stack. When the function ends, the stack pointer is reset to it's original value, possibly with destructors for the things on the stack being called. Also, in modern compilers, parameter variables are mostly passed to functions via registers, with the stack not being involved at all.
- andi999 5y agoSince this would be too easy for c++, there is also (sometime mandatory) copy elision.
- mhh__ 5y ago> Also, in modern compilers, parameter variables are mostly passed to functions via registers, with the stack not being involved at all. Given that this is a C++ thread I'll be pedantic and say that this is really the ABI rather than the compiler as per se.
- gumby 5y agoABI is a factor in every language;* so I’m not sure I understand the point you’re trying to make. * even interpreted ones, though the calling conventions and layout are quite different from what is typically written up in the documentation of most compiled languages.
- mhh__ 5y agoThe term "modern compiler" was used, which implies that an old compiler might (say) not do so despite complying with some ABI, i.e. the registers aren't an optimization.
- zabzonk 5y agoGiven that the C++ Standard has nothing to say about an ABI (neither does the C Standard, for that matter), then what a compiler does on a particular platform, and what a platform ABI specifies (if it does) are possibly kind of linked.
- mhh__ 5y agoThe word compiler is only mentioned 12 times in the whole standard give or take. My point was that it's not a question of whether the compiler is modern or not, i.e. I work with an old compiler backend on a modern system and it still gets the ABI correct even if it ends up spilling back to memory too often.
- brundolf 5y agoI took it as a "conceptual abstraction". It presented a mental model focused on the relationship between variables' lifetimes, intentionally glossing over the implementation details of any particular compiler.
- Someone 5y agoIf it is glossing over implementation details, why does it mention the stack? That _is_ an implementation detail. AFAIK (I never looked at an official standard, only at drafts) the standard doesn’t mention the word “stack” at all A C++ compiler is free to allocate environment frames for every block on the heap.
- brundolf 5y agoThere are different tiers of abstraction. This post picked a level of granularity that the author felt would be helpful for a certain subset of readers. Whether the "stack" is formalized or not, it's the mental model (and the vocabulary) that's most often used when working with this stuff. I don't think there's anything wrong with the fact that they focused on the forest and not the trees.
- Someone 5y agoYes, there are different tiers of abstraction, but I think this article, about lifetimes, would be better if it just discussed scope. As is, it goes into implementation details for block scoped storage, but just posits that new and delete exist without mentioning any detail. That’s unbalanced. Rereading it, it also assumes you know C well enough to know about malloc, so maybe, just saying “C++ can automatically do stuff when variables go out of scope or when you allocate or free memory. Here’s what it can do…” might be sufficient)
- jcelerier 5y ago> When variables are allocated on the stack, the space for them with all compilers I have ever used (or written) is allocated on the stack once by adjusting the stack pointer - i.e. for all of the variables of the function. it's not a given int algo(int*, int n); int computation(int i, int n) { int alloc[n]; return algo(alloc, n); } on some compilers (Keil for instance afair), alloc will be heap-allocated (and freed when leaving the function) even if it's "automatic storage" (what most people call the stack).
- divingdragon 5y agoIsn't variable sized array non-standard in C++? Variable sized array is kind of a special thing anyway so I wouldn't be surprised if some compilers do something special with it. Yes, the term "automatic storage" is more accurate here.
- dxuh 5y agoAs you are officially discouraged to use new and delete directly (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r11-avoid-calling-new-and-delete-explicitly https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines...) and I fully agree with this guideline, I was disappointed to see new being mentioned so early and not immediately being followed up with std::unique_ptr and std::shared_ptr. Especially because you introduced the constructor/destructor subsection with how destructors can be used to free memory. A general mention of std::shared_ptr would have been expected as well, I think. It is unfortunate that many learning resources don't show modern C++ so the language is perceived worse than it is and also more bugs are written, than is necessary.
- zabzonk 5y agoIn my opinion, the site you linked to has a major problem - many of the example functions have a "void" return type. This indicates that they must have side-effects (or why else call them?) and we would normally not want to write functions that have side effects. A rule of thumb: if your function doesn't have a return type, consider that your design maybe wrong in some way.
- detaro 5y agoWhat the functions return is utterly irrelevant for the examples, so adding return types and statements just makes the example more complex for no good reason (and distracts from examples where the example is about the returns)
- zabzonk 5y agoThe site is about writing "good" C++. Having loads of functions that implement "bad" C++ cannot help.
- josefx 5y agoGood C++ code shouldn't throw around heap allocations, shared or otherwise. Smart pointers are like duct tape, they help keeps things together but most of the time there are better solutions. Your complaint about void will be noted once you fix your programs ownership semantics. Note: Any negative reactions to smart pointers on my side may be fueled by a disturbing amount of cargo culting that I had to witness since their inclusion in the standard.
- layoutIfNeeded 5y ago>This means it allocates memory from the heap, named after the heap data structure Oh my god, please don't write articles about things that you barely understand!
- minipci1321 5y agoAnother one: > the exact order that C++ evaluates expressions is extremely complicated and not always defined, ... " "(Un)defined" and "unspecified" (which order of evaluation of fun-args really is) are two distinct terms in the C++ spec meaning different things, they cannot be used interchangeably. But I guess it's just yet another thing of "Pedantic assembly-code analysts"...