News for hackers. Stuff that matters.
Re:Memory management in C programs (2014) by lmm on Tuesday July 19, 2016 @07:10AM (#12121032)
Being able to construct without initialising is the flipside of being able to descope without deinitialising, and introduces much the same problems. It makes it much harder to use immutability (admittedly something that's hard in C++ in any case). It makes sharing objects between threads much harder to reason about, as you need to make sure init a) only happens once, but more importantly b) the effects are visible to any other thread before it uses the object.

How much code have you written with exceptions? A lot of features you don't miss if you don't use them, but once you're used to use them it's very frustrating to live without them. Back when I wrote C I never thought "gee it would be nice to use an anonymous function here", but now that I'm used to them it's very frustrating to not have them.

Re:Memory management in C programs (2014) by flohofwoe on Tuesday July 19, 2016 @10:16AM (#12121887)
Admittedly I haven't written much code with exceptions, only when using C++ frameworks that heavily rely on them, but this was always for tools where productivity was more important than performance, my actual background is game development.

I have stumbled more recently over another case where the constructor/destructor paradigm in C++ is not ideal, since in some cases it 'encourages' constructing objects on the heap, just for the reason that allocation and initialisation are the same operation, I haven't thought this completely through yet, but bear with me:

Basically I'm trying to write code in a way that minimizes heap allocations. In the extreme case I have just one big 'application object', and all other objects are embedded in this application object. For variable number of objects, pools/arrays with the max capacity are embedded. If taken to the extreme, this model only does a single allocation at application startup (or it could even live on the stack).

However, there are systems which need to be initialized later, and in a specific order (for instance rendering, audio, input, etc...). The objects for these systems have already been created and had their constructor run, but they are not ready for use. That's where I need separate initialisation steps, unless I want to put those objects back on the heap. And in reverse, I need to teardown graphics, audio, input before the big application object is destroyed (and the destructors of the embedded objects are called).

Now I don't think that this extreme case of trying to minimize dynamic allocations down to 1 is particularly useful in real world code, it's more of a though experiment, but in this case, the good ol'e C way of separating allocation/deallocation from initialization/teardown is actually more useful.

Unfortunately I have stumbled over C++ frameworks which basically require to create all objects on the heap, which in my opinion is a design fault. A framework should not dictate to its users whether objects are created on the stack, on the heap, or are embedded in other objects.

Re:Memory management in C programs (2014) by lmm on Wednesday July 20, 2016 @06:46AM (#12128037)
I agree that developers and code can have a lot of knowledge that lets them make allocations a lot more efficiently than the likes of glibc's malloc() (which have to handle a lot of edge cases and a lot of different workloads). As an extreme example, if you can architect around cooperating short-lived processes (Erlang-style) you can use a simple bump allocator and "dynamic" allocation is effectively (almost) free.

I wouldn't want to be doing anything custom around allocation without the support of a type system though. Having allocated-but-not-fully-initialized objects hanging around and looking exactly like fully-initialized objects is a recipe for disaster, and while it may be possible to keep track of things yourself through constant vigilance, the cognitive load just isn't worth it IMO. So if I had to do that kind of thing in C++ I'd probably look at having a custom allocator and some way to pass hints to it, rather than doing allocation and initialization separately in "normal" code. (Well, in reality I wouldn't use C++)

> Unfortunately I have stumbled over C++ frameworks which basically require to create all objects on the heap, which in my opinion is a design fault. A framework should not dictate to its users whether objects are created on the stack, on the heap, or are embedded in other objects.

Depends on the use case IMO. The flexibility of being able to control all your objects is valuable, but it doesn't come for free. One can't really generalize about what's idiomatic C++, because there's such a broad range of users.

Re:Memory management in C programs (2014) by richardwhiuk on Tuesday July 19, 2016 @10:07AM (#12121839)
You can perfectly well have classes which have different levels of initialization and clean them all up in the destructor...

RAII is generally useful without exceptions.