Comment by marcosdumay

7 years ago

Non-C++ developers are usually awed by it. The animosity comes from people with experience in C++ that decided not to use it.

Pre-11 C++ was a bad language. The gains of leaving it to something like Java (that isn't even good by today's standards) were huge. The new standards are making it possible to create better code on the language, but it is still far from a modern language and the added features can not remove complexity, they can just add to it.

> the added features can not remove complexity, they can just add to it

There are countless examples of the so-called modern C++ features reducing complexity in code.

For example, it is now considered a code smell to ever write "new" or "delete" in your code. Imagine that, never using these words to manually allocate and delete memory in C++! But it's true, unique_ptr in particular makes so much simpler and safer.

Type inference with auto doesn't just save typing, it improves performance in many cases and reduces a lot of complexity, while also avoiding uninitialized variables.

These are just a few of at least a dozen examples that come to mind about reducing code complexity with more modern C++ features.

  • New features can reduce the complexity of code, but they cannot reduce the complexity of the language.

    C++ programmers still need to know what "new" and "delete" do, so they can work with older code that uses them. They also need to learn what "auto" does, so they can work with newer code that uses it. (The behavior of "auto" isn't trivial; how many C++ programmers understand the difference between "auto v = <expr>;" and "decltype(<expr>) v = <expr>;"?)

  • I hate unique_ptr and shared_ptr, using them is so glaringly inconsistent. Half the time you can’t construct a unique_ptr when it’s easy, because you don’t have the information until just enough later (like after a calculation or two in the body of your constructor) that you can’t use the easy way. So how do you transfer a unique_ptr? Well, the obvious ways don’t compile, and you eventually learn you have to move it, which involves using std::move(), but it always seems to go in the place I don’t expect it. And then how do you use a unique_ptr outside of your class? You can’t pass by value, for obvious reasons. Pass by reference, maybe? I think that’s frowned upon, I think you’re supposed to pass a naked pointer, and Modern C++ code is supposed to understand that naked pointers mean I’m loaning you this pointer. But I thought the point of Modern C++ was to get rid of pointers? Anyway, shared_ptr works completely the opposite way. You are supposed to pass the pointer by value. Now you can argue that of course it’s supposed to be that way, and the arguments are all cogent and when you spend half a day figuring it all out it makes sense. Until tomorrow when you forget it all and have to actually use the things. Plus I hate underscores with a passion, it hurts to type them. Modern C++ also seems to like making a line of code longer and longer, because you can’t just make a unique_ptr or shared_ptr with a constructor, no, you need make_unique<typename>(...), and the arguments are magically the same as the type’s constructor, even though it’s obviously a different function. Yuck! At least new and delete are pretty obvious how to use, and only have one special case to worry about ([]). Granted, the *_ptr are better, but I hate using them and wish I could use something that was shorter and easier to remember.

    • > I hate unique_ptr and shared_ptr, using them is so glaringly inconsistent.'

      They're glaringly inconsistent because they behave differently with regards to ownership, and the fact that you can't copy them or pass them around in certain cases is because they're designed to stop you from doing this as it would undermine the reason you're using the class.

      1 reply →

    • FYI, you can use a constructor with a shared/unique ptr.

      auto p = unique_ptr<Foo>(new Foo());

      Totally works, and may be easier to remember if you dont like the "magic" parameter forwarding.

      3 replies →

    • The vast majority of the time you just want to pass a reference to the pointed-to object (for both unique_ptr and shared_ptr). Once you've decided what you're actually going to do with the object, that usually determines how you're going to want to pass it.

    • > But I thought the point of Modern C++ was to get rid of pointers?

      no it's not, it never has been. The point of modern C++ is to get rid of owning pointers.

  • How does auto improve performance? Doesn't it just expand to whatever type a human would have manually had to put there in the first place?

    • It allows automatic generic specialization in some cases by the compiler, as you don't have to do template-fu or use a nonspecific type or manually write multiple specializations.

      Plus it usually makes the code cleaner by focusing on structure not types. As any construct, it can of course be abused.

I disagree that pre-11 C++ was bad. It would be bad now to make a new language that looked like pre-11 C++ but there is a reason it was so popular.

  • Its a bit like IE6. A big upgrade over C but the next update took so long that it was hated at the end of its life. Which coincidentally is exactly why C++ now does timed releases.