4 ms·
> For example, once you’ve allocated and de-allocated C structs a few times, you realize it would be good to have functions to do this allocation and de-allocat
by jstimpfle 8y ago
> For example, once you’ve allocated and de-allocated C structs a few times, you realize it would be good to have functions to do this allocation and de-allocation. You basically end up re-inventing C++ constructors and destructors.
Conflation of resource allocation on the one hand and construction (a.k.a. initialization) on the other.
Good C programmers do not re-invent C++ constructors and destructors, because they don't think what C++ constructors do is a good idea to do.
While C++ allows to separate allocation and initialization ("placement new") that goes against the grain of the language and its ecosystem. You're still left with constructors new-ing nested things themselves, and you're still left with exceptions from constructors while a simple return value would be better.
> A typical C or C++ programmer simply will not write anything more efficient or more robust than the methods in these libraries if they decide to roll their own.
A typical C programmer will write something different in the first place. Something that doesn't take ages to compile. Something that doesn't do allocations behind their back. Something that doesn't spew out nigh unreadable error messages if they got a simple thing wrong. Something that doesn't encourage clever code that isn't doing anything useful. Something that doesn't require loads of boilerplate and duplication (thinking of const for example) for the simplest task.
- zozbot123 8y ago> Conflation of resource allocation on the one hand and initialization (a.k.a. initialization) on the other. a.k.a. RAII (Resource Allocation Is Initialization). Which is very often what you want anyway.
- CoolGuySteve 8y agoJust because it has a name doesn’t make it a good idea necessarily. What one calls “initialization” someone else might call a “side effect”. In particular, sometimes you don’t want a bunch of allocations and locks firing on every function call and exit. C makes this behaviour explicit and C++ makes it implicit.
- bunderbunder 8y agoAs others have said, it depends on your context. If you need to be able to maintain tight control over resource usage, for example, RAII creates challenges. It can also be a bit of a chore to think about if you're doing interop with other languages. I've come to think of C++ as the tiktaalik of programming languages: It can live in two environments, and was an important evolutionary step in transitioning from one to the other. But, ultimately, it embodied so many design compromises that it was never going to be ideally suited to either of them.
- gpderetta 8y agoSeparation between allocation and construction is a fundamental part of the C++ language, performed by different functions. I'm not sure why you think that placement new is against the grain of the language, it is what allows non-intrusive yet inline data structures in the first place. Re constructors newings things, one still has the option of passing the preallocated objects via constructor parameters, or customize allocation via an allocator. The language itself doesn't have a preference.
- jstimpfle 8y agoResource Allocation Is Initialization is one of the central themes in C++. > one still has the option of passing the preallocated objects via constructor parameters, or customize allocation via an allocator I'd rather just allocate_the_thing(); initialize_the_thing(); do_things_with_the_thing(); free_the_thing(); which makes it very easy to pull these farther away from each other, or to perform bulk operations over many "objects". In other words, I just want to do what needs to be done, when it needs to be done, and not have to build and use awkward semantically heavy trap doors (rvalue references?) to not do the systematic things that weren't a good idea in the first place.
- gpderetta 8y agoThe A in RAII is for acquisition and it is about ownership, not allocation. You can do exactly those things in C++ (operator new or allocators, T::T(), T::~T(), operator delete). The language just gives the tools to distinguish a bunch of uninitialized memory from an actual T which holds its invariant (if any).
- jstimpfle 8y agoOk acquisition it is. I don't even understand the difference. Wikipedia doesn't seem to make a distinction either. Uninitialized memory is all I ever want. And I want to simply write to that memory when the time has come, not hide those writes in a T::T() somewhere in an isolated file with lots of braces and spaces and colons and only few things that actually happen. It's really hard to map out the codepath of a project with lots of constructors and inherited constructors 15 levels down the call stack. Same applies for running it in a debugger.
- x0re4x 8y agoThere is a good comment after the article: "The simplicity of C is more useful than the additional features of C++." -- (Sam Watkins)