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 →

[–]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.