Live data from Hacker News

You can't make C++ not ugly, but you can't not try (2010)

apenwarr.ca

161–170 of 187 posts

Re: You can't make C++ not ugly, but you can't not try (2010)

#161
post #121

Earlier quoted context omitted.

You wish. Unless I'm terribly misinformed, "modern C++" contains all of the features of the prior versions, which means that in the real world you have to learn and deal with all of it .

I don’t really understand your point. Just because all the implementations support the `asm` keyword doesn’t mean you need to know the assembly language of every CPU that has a c++ compiler. You can write your code in modern c++ and ignore prehistoric carbuncles (some of which have been deprecated and eliminated FWIW). And you can call external code written in older dialects without having to look into its source cod…

That's great for a greenfield project where you're the only developer. If it's multiple people, you have to deal with whatever subset the powers-that-be on your team wish to use. If it's not greenfield, you have to deal with the subset exists in the codebase.

And if you're a Dirty Harry type like me, debugging issues with dozens of disparate codebases written in various crap subsets, you pretty much have to know the whole cursed thing.

Re: You can't make C++ not ugly, but you can't not try (2010)

#162

Earlier quoted context omitted.

You have that backwards. The STL containers are for when you have a hyper-specific niche use case. They are otherwise terrible defaults and everyone should use boost or abseil by default otherwise. std::map, for example, is only appropriate if you need a red-black tree specifically. Which almost nobody does. std::unordered_map is less awful, but abseil has a literal straight upgrade. With the same API. So... why woul…

Small vectors break iterator guarantees, for one thing. They also really only make sense for tiny objects (ints, etc.) given you don't want a pickup truck's worth of data on your stack. They're most definitely not general-purpose. There are lots of subtleties STL containers have to worry about in designing containers, regarding everything from iterator & pointer invalidation to allocation and allocator propagation. A…

> Small vectors break iterator guarantees, for one thing.

It only breaks swap of the container itself during iteration. Which is a super niche condition.

And that swap also invalidates some of std::vector's iterators as well - specifically the end() iterator.

> They also really only make sense for tiny objects (ints, etc.) given you don't want a pickup truck's worth of data on your stack. They're most definitely not general-purpose.

Of course they are still general-purpose. They can (and do) specialize on the size of the object being contained. The only reason std::vector doesn't also have SSO is because it's an ABI break. Not because it's better in some way or less fragile. Legacy is the only reason.

Re: You can't make C++ not ugly, but you can't not try (2010)

#163

Earlier quoted context omitted.

You wish. Unless I'm terribly misinformed, "modern C++" contains all of the features of the prior versions, which means that in the real world you have to learn and deal with all of it .

> which means that in the real world you have to learn and deal with all of it. This is not what happens in the real world though. While I agree that you have to deal with whatever is in your codebase at a given point, it also doesn't imply that you have to use everything and that everything can be useful for your project. As standards keep coming and features get added, it's still increasingly prevalent to see guide…

In my world (see other reply), I get to deal with whatever is in dozens of codebases written in many times and places. The superset of everything they're using is pretty much everything.

Beyond that, even the "good" modern subset of C++ is crazy complex. I've sat in a room with some of the better C++ programmers in the world while they study and try to comprehend the new features like rabbis interpreting the Talmud.

If there's one concise, fundamental rule of software engineering, it's this: Complexity kills.

Re: You can't make C++ not ugly, but you can't not try (2010)

#164

Earlier quoted context omitted.

You wish. Unless I'm terribly misinformed, "modern C++" contains all of the features of the prior versions, which means that in the real world you have to learn and deal with all of it .

> which means that in the real world you have to learn and deal with all of it. That makes as much sence as claiming that to develop software in, say, Python on the real world you have to learn and deal with all of its standard library. That is not the case. That has never been the case ever for any programming language, be it large or small. Specially in C++, where since it's inception the standard approach is to, a…

If your job involves maintenance or support of multiple Python codebases, you do have to learn it all. And at least before Python 3, this wasn't that hard. (Python 3, unfortunately, has made the language a lot more complex.)

Re: You can't make C++ not ugly, but you can't not try (2010)

#165

Earlier quoted context omitted.

Making a language so big and complex that you can't expect to understand it all isn't a good idea. You might be able to get away with using 50% of the language but if some project you depend on uses a different 50% then you have a problem.

IMHO C++ is unfairly singled out with regards to it's extension. That criticism rings true if applied to pretty much every single programming language ever devised, including "small" languages such as C.

C, even today, fits entirely in my head. C++ does not.

I suspect this is not an uncommon situation among programmers.

Re: You can't make C++ not ugly, but you can't not try (2010)

#166
post #131

Earlier quoted context omitted.

OK but if you're a competent, adult software engineer it should be fairly easy to overcome that problem.

> OK but if you're a competent, adult software engineer "No true Scotsman" and all, please refrain from posting messages that add nothing of value besides petty insults thrown in broad brush strokes.

Much as I didn't mean to insult anyone with my post, I'm sure you meant to add value by calling it petty and fallacious.

Picking up features in a language you already use is easier than learning the language to begin with which itself is easier than learning to program at all. If you were able to read the documentation to get to 50%, you have all the skills needed to pick up the rest and get to the difficult part of picking up a new project: understanding the problem space. If you're capable of learning the meaning of an API you've never seen before - and you will, if you're not writing your last project verbatim - then you're capable of learning what a lambda means. This is not me saying that all programmers should be able to do this, it's me saying that doing this is a predicate of engineering software.

Re: You can't make C++ not ugly, but you can't not try (2010)

#167
post #18

Earlier quoted context omitted.

To the contrary, modern C++ has solved very few, if any, of the problems described in the article. Being generous: * There's now `std::string_view` to address some of the problems with `std::string`, but the rest are still there. There are some attempts to specify the encoding now, at least. * Lambdas and `std::function` pretty much solve the function pointer complaints, with some added complexity. * Containers still…

> To the contrary, modern C++ has solved very few, if any, of the problems described in the article. The author, after a long and dubious appeal to authority, claims that: * C++ exceptions are outright evil and should be avoided * C++ string class "is so utterly godawfully stupid" because it has no garbage collection or refcounting, and in short doesn't precisely match Python's implementation. He also felt personally…

You're not wrong, I wrote off the insubstantial stuff as rhetorical and started my comment with "being generous." :P

But on the other hand, even some of these less-helpful points have an element of truth:

* A lot of people/domains/codebases do wind up avoiding exceptions, for good reason. There is even an active proposal to provide an alternative kind of exceptions to solve their problems!

* Member function pointers are quite a mess, introducing a lot of complexity by not being compatible with regular function pointers. It wasn't until long after this article that those incompatibilities were papered over with the standard library.

* std::map::operator[]'s behavior arguably does not follow the principle of least surprise- it's a giant footgun.

The author goes out of his way to point out that the changes he wants don't require GC or an interpreter, despite all the comparisons to Python. It's not an insubstantial comparison in that light.

Re: You can't make C++ not ugly, but you can't not try (2010)

#168
post #131

Earlier quoted context omitted.

OK but if you're a competent, adult software engineer it should be fairly easy to overcome that problem.

Then why is it so common for people to try and select a subset of the language. Arguing about what people should do is pointless, you have to look at what they do do.

If there are multiple ways of achieving the same result (e.g. assignment) and you want to be consistent, you have to choose a subset. If there are features that time has shown to be less-than-ideal (e.g. malloc/free) you choose a subset while the language avoids removing breaking backwards-compatibility.

So when you go to another project that made different decisions, what you should do is understand the decisions. It's quite easy. And that's why it's what people do do, and it's why people are capable of contributing to projects other than their first.

If you program in C++, it's the same skill you used to learn one or more of {CMake, Makefiles, scons, bash, python} except it's easier because you already understand the programming language's model.

Re: You can't make C++ not ugly, but you can't not try (2010)

#169

Earlier quoted context omitted.

Small vectors break iterator guarantees, for one thing. They also really only make sense for tiny objects (ints, etc.) given you don't want a pickup truck's worth of data on your stack. They're most definitely not general-purpose. There are lots of subtleties STL containers have to worry about in designing containers, regarding everything from iterator & pointer invalidation to allocation and allocator propagation. A…

> Small vectors break iterator guarantees, for one thing. It only breaks swap of the container itself during iteration. Which is a super niche condition. And that swap also invalidates some of std::vector's iterators as well - specifically the end() iterator. > They also really only make sense for tiny objects (ints, etc.) given you don't want a pickup truck's worth of data on your stack. They're most definitely not…

> And that swap also invalidates some of std::vector's iterators as well - specifically the end() iterator.

And they don't invalidate the iterators that point to actual elements, which was kind of the entire point I was making. Don't let that stop you from trying to make it look like I'm just blurting out nonsense, though.

Re: You can't make C++ not ugly, but you can't not try (2010)

#170
I 100% agree with the title, but some of the complaints in this article have been addressed since the article was published by C++11, C++14, or C++17. Others are just weird.

> If you've heard anything about C++, you've probably heard that there's no standard string class and everybody rolls their own.

Is this still true? std::string seems perfectly reasonable now, especially now that they've given up on supporting ropes and integrated the small string optimization. Yes it doesn't specify an encoding.

> No garbage collection? Check. No refcounting? Check. Need to allocate/free heap space just to pass a string constant to a function?

Nothing else in the standard library is garbage collected or refcounted by default. Why would std::string be the lone exception? You can opt into refcounting for any type using std::shared_ptr.

The objection about allocating/freeing heap space is about APIs that take const std::string& being passed C-string literals. Legitimate complaint, but it's addressed by std::string_view now.

> ...rant about lack of []= operator...

[] mutating the map does surprise people, so that's definitely a legitimate complaint. And it is annoying to have to use find() in a const context...

but simple operations like counting are simpler and more efficient in C++ than in Python because the +=, -=, etc operators work:

  for value in list:
    counts[value] = counts.get(value, 0) + 1
vs

  for (auto& value : list)
    counts[value]++;
> So actually C++ maps are as fast as python maps, assuming your compiler writers are amazingly great, and a) implement the (optional) return-value optimization; b) inline the right stuff; and c) don't screw up their overcomplicated optimizer so that it makes your code randomly not work in other places.

This is just comical. Python is not playing in the same performance league as C++, regardless of whether inlining or RVO happens. RVO of course is a general optimization for returning objects by value from functions, not a special case to optimize setting map items. It's still relevant, but less important since C++11's move semantics.

Post reply on HN