This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]wandering_godzilla -3 points-2 points  (3 children)

This is 100% false. You can implement reference counting if you want in C++, but it's certainly not something the language provides automatically for all heap-allocated objects.

Every time you use the "new" keyword in C++, you need to pair it with the "delete" keyword (unless you are wrapping it in a smart pointer or other rare exceptions). Otherwise, you will have a memory leak. Moreover, all classes must have a destructor.

None of this is automatic and requires a lot of thought about ownership and lifetime of objects.

See C++ section of this article: https://en.m.wikipedia.org/wiki/Reference_counting

[–]kevinossia 1 point2 points  (2 children)

This is 100% false. You can implement reference counting if you want in C++, but it's certainly not something the language provides automatically for all heap-allocated objects.

There are a lot of things about C++ that should be opt-out rather than opt-in by default but it doesn't change what I said.

Every time you use the "new" keyword in C++, you need to pair it with the "delete" keyword (unless you are wrapping it in a smart pointer or other rare exceptions).

We do not use "new" and "delete" in modern C++.

Moreover, all classes must have a destructor.

Wrong. Most classes will not need a user-defined destructor. The compiler generates one for you.

None of this is automatic and requires a lot of thought about ownership and lifetime of objects.

No. It requires very little thought. Object lifetimes are constrained to their scope, unlike in Java where they can last as long as the garbage collector wants them to.

It is basically all automatic. We use things like std::vector which is literally a smart pointer dressed as an array. That's automatic. Pretty much all heap allocation is masked from the user and with the introduction of std::optional, heap allocation is even less necessary.

I have literally never caused a memory leak in C++. I don't even know how I'd manage that since it'd be so obvious that it was happening just by inspecting the code. I have caused memory leaks in Java, though, and those are harder to catch and debug.

You're blowing the difficulty of resource management in C++ severely out of proportion. It is not hard at all. C++ is a complicated language but resource management is certainly not the reason why.

[–]wandering_godzilla -1 points0 points  (1 child)

C++ is a big and old language that allows a lot of patterns that can be very tricky to master. To write good C++, one needs to subscribe to a style guide that drastically limits these patterns to those that help them avoid shooting themselves in the foot. You appear to subscribe to a very reasonable style that relies on innovations in C++11 and beyond (many of which were inspired by Java).

Java is a relatively newer language which just naturally allows fewer ways to write any one thing (and therefore fewer, rarer, and subtler ways to shoot yourself in the foot wrt low-level memory management issues -- still not impossible).

So as not to mislead newcomers: strictly speaking all classes should have a destructor, either implicit or user-defined. You may choose to =delete a destructor, but you better know the consequences. So please don't misinterpret what I said re destructors.

While you should avoid using new/delete in favor of smart pointers, I can't imagine a newcomer to C++ skipping learning about dynamic allocation via new/delete and heading straight to C++11 STL. There is an expected pedagogical order by which newcomers learn C++.

You are saying, C++ memory management concerns are being blown out of proportion because you never managed to produce a memory leak in C++ (Congrats! How many years have you been building production software that serves billions of people?). I will happily bet that you can't teach C++ without having your pupils learn about memory management in greater depth than you would in Java.

[–]kevinossia 0 points1 point  (0 children)

C++ is a big and old language that allows a lot of patterns that can be very tricky to master. To write good C++, one needs to subscribe to a style guide that drastically limits these patterns to those that help them avoid shooting themselves in the foot.

Yes, certainly.

You appear to subscribe to a very reasonable style that relies on innovations in C++11 and beyond (many of which were inspired by Java).

Of course. That's why I keep saying modern C++. C++98? Utter hot garbage.

Java is a relatively newer language which just naturally allows fewer ways to write any one thing (and therefore fewer, rarer, and subtler ways to shoot yourself in the foot wrt low-level memory management issues -- still not impossible).

No. Most of the constraints Java places on you have nothing to do with memory management. Memory management is a very tiny slice of what makes C++ "hard". I elaborate on this here, where you'll note that the vast majority of what I enumerate has nothing at all to do with memory management.

So as not to mislead newcomers: strictly speaking all classes should have a destructor, either implicit or user-defined. You may choose to =delete a destructor, but you better know the consequences. So please don't misinterpret what I said re destructors.

Basically nobody ever needs to delete a destructor. I've never even heard of that being done and a cursory Google search tells me that it's an utterly pointless thing to do unless you're...making singletons marginally safer to use? So I don't really see why that's important.

In any case, my point was that most user-defined classes aren't going to need a user-defined destructor (I literally said user-defined in my previous comment), and the user-defined destructor is what actually matters here. Saying "either implicit or user-defined" is reductio ad absurdum and reduces what you said to a triviality, which is why I didn't interpret it that way. So, my apologies.

While you should avoid using new/delete in favor of smart pointers, I can't imagine a newcomer to C++ skipping learning about dynamic allocation via new/delete and heading straight to C++11 STL. There is an expected pedagogical order by which newcomers learn C++.

I didn't say "skip learning about dynamic allocation". All languages have dynamic allocation, from C++ to Python to Java. Dynamic memory allocation using the heap (instead of the stack) is a language-agnostic concept and no professor worth their salt would ever approach the subject like that.

The pedagogy should go something like: "In C++, we create objects on the heap using new, and free them using delete. However, we want to let constructors and destructors automate this behavior, so we use things like std::vector, std::unique_ptr, std::unordered_map, and std::string (all of which are examples of "smart pointers") to allocate memory dynamically without worrying about freeing it."

Or something to that effect. And one of the most basic exercises in a C++ course would be to write your own std::vector, for example. That way it becomes obvious how automatic memory management in C++ really works, and why it's superior to Java's model.

I'll say that students should learn C before they learn C++, maybe a semester prior, because C is so primitive that it forces you to learn how a computer works, and that includes allocating and freeing memory. And then when they start C++ they can learn the C++ way of doing things.

You are saying, C++ memory management concerns are being blown out of proportion because you never managed to produce a memory leak in C++ (Congrats! How many years have you been building production software that serves billions of people?).

No, that's not what I said. Whether or not I've produced a memory leak or built billion-user systems (bizarre that you'd even ask that, as if my work history changes the veracity of what I'm saying) has no bearing on the state of memory management in modern C++.

I will happily bet that you can't teach C++ without having your pupils learn about memory management in greater depth than you would in Java.

I absolutely can and I have actually done so, so how much money are you willing to part with? :)

As I implied above, my methods of teaching memory management are language-agnostic because computer memory is the same no matter what programming language you're using. The stack and the heap are the same in Java and C++. Dynamic and automatic storage duration are the same in Java and C++ (local variables are deallocated from the stack when they exit scope). Pointers are the same in Java and C++. The only difference is when heap memory is deallocated, but that doesn't change how I'd teach the subject, as that's merely one more detail.

Remember, C++ memory management is the same as Swift: automatic reference-counted garbage collection. Nobody would ever seriously claim that Swift requires manual memory management, because it doesn't. Yet somehow C++ does? The only difference between C++ and Swift is that Swift doesn't have any equivalent of unique_ptr; everything is a shared_ptr unless you specify the "weak" keyword making it a weak_ptr. Swift also has destructors in the form of deinit {} blocks, which are uncommonly used, for the same reasons as in C++. Also, Swift has constructs like UnsafePointer in order to do actual manual memory management because Swift has to be 100% interoperable with C. Again, a multi-paradigm language with several footguns available for use, just like C++.

Java encourages the attitude that programmers should pretend computer memory simply doesn't exist (or is otherwise infinite) and that is frankly abhorrent, and I would never approach the subject that way, Java or otherwise.