Live data from Hacker News

Orthodox C++ (2016)

bkaradzic.github.io

131–140 of 238 posts

Re: Orthodox C++ (2016)

#131

If you're in a market that requires using C++, many of these decisions are made for you by the platform above you, and you're screwed. Turn on RTTI, build a fort to deflect the random exceptions they'll throw at you, and may the gods allow you to recoup your R&D before some well-intentioned yokel in some media or game vertical changes everything and requires you to change everything. On the other hand, if you control…

> build a fort to deflect the random exceptions they'll throw at you Sounds like you hate exceptions, right? In which case why do you handle them at all? Just leave them all unhandled and suddenly every exception is a crash. Which is really no different from someone choosing to terminate. Which you have to worry about even without exceptions. > if you have a C++ code base yet somehow have enough time and energy to wr…

> Sounds like you hate exceptions, right? In which case why do you handle them at all?

One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are.

My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors.

Python is the bloody worst because I never effing know what the hell any damn function can throw or return. It’s so so frustrating.

Error handling is a hard and unsolved problem. But I’ll take Rust results over exceptions 10,000% of the time. Not even a question.

Re: Orthodox C++ (2016)

#132
post #94
post #51

Earlier quoted context omitted.

Like implementing the compilers used by C devs.

GCC was implemented in C and there are plenty of other C compilers written in C. GCC has been converted to C++ at some point, but large parts are still essentially C and I do not think the change to C++ was actually helpful (but others may disagree). In any case, the idea that one needs C++ to have C compilers is certainly simply wrong.

My original C compiler was implemented in C and then bootstrapped. Zortech C++ was implemented in Zortech C, and then bootstrapped.

D was implemented in "C with Classes" and then translated to D and bootstrapped. There isn't a line of C code in it.

Over time, we gradually replace the C-isms and C++isms and anachronisms in it to native D-isms.

Re: Orthodox C++ (2016)

#133
post #83

Earlier quoted context omitted.

and even std::map, std::unordered_map, even std::vector (!) suck It's really hard to take your comment serious because of generalization like this. Maybe they're not usable for your particular usecase but that doesn't mean they suck. Just like there's a 'million' ways that C++ sucks in your book, there's a reason there's millions of lines of code out there where these containers are valid usecases and hence work with…

std::map and std::unordered_map are just unbelievably shitty implementations. The former is a red-black tree, which in my entire programming career I have needed to reach for like... twice? It's just not the right container for almost any problem you have, yet it's the one that gets the short, sweet name. The latter is a bucket-based hashmap, which is about the worst kind of hashmap that can be built. On top of that,…

Pretty much the only collections I use are:

1. arrays

2. linked lists

3. hash tables

4. simple binary trees

Re: Orthodox C++ (2016)

#134

Earlier quoted context omitted.

They're just clearly inferior in pretty much any situation. The map stuff the other posters summed up well but even std::vector is dogshit with pretty much all implementations having inlined grow code in push_back, a not too great API and missed optimisations e.g. no trivial relocation when growing the vector / moving it and no useful APIs such as "grow but don't initialise"...

To be fair grow-but-don't-initialize is a pretty fundamental part of the API, the reserve() method. But already the basic premise that you should push back without thinking is wrong. You will suffer reallocations and invalisations when you least expected them, and frankly you have to architect around that fact which is a terrible restriction. You can work around by pre reserving but at that point it's just a basic fi…

std::vector lacks what I call the "bifurcated reservation API". It has Rust's Vec::reserve_exact but not Vec::reserve -- these APIs serve subtly different purposes, the former (which C++ calls just "reserve") says "Here's a hint for exactly how big this container will ever grow" while the latter says "Here's a hint for how big this container will get in my immediate future, but it might grow further later".

The implementation always tries to grow (if necessary) to the exact size chosen for Vec::reserve_exact, but for plain Vec::reserve if growth is needed it always grows exponentially, not to the exact size, preserving the O(1) push cost.

For a typical "doubling" growable array type, if we're pushing groups of ten items, reserve_exact or C++ grows like 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ... which is much worse than O(1) whereas the correct reserve grows 10, 20, 40, 80, 160 preserving O(1)

For trivial types you can work around this in C++ with a little work, and for the non-trivial types you can work around it with a bunch more extra code, but you probably won't.

Bjarne among other people teaching C++ recommend just not using the reservation API as a reservation API because of this problem†, and the resulting teaching definitely leaks into CS graduates and even into languages which have the correct API and so you have to un-teach the bad lesson.

In applications where you actually can't afford to pay for growth (or at least in some cases can't afford this) I also like Vec::push_within_capacity which I believe comes from Rust for Linux where the kernel legitimately needs this "If there's room push, otherwise I have a plan B" approach.

† To Bjarne this API is instead conceived of as a way to preserve reference validity. Since it won't grow, our references will still work.

Re: Orthodox C++ (2016)

#135
post #8

Earlier quoted context omitted.

One thing I've noticed about a lot of these "strict C" developers is that quite often they actually refuse to learn C++. One of the most common complaints of C developers regarding C++ is "it does things behind the scenes/performs magic", often with regards to operator overloading. When they refuse to actually look at the implementation (y'know you can check if an operator has been overloaded) AND they refuse to ackn…

All the foot guns in C are still in C++, and C++ adds a significant multiple more.

Literally untrue. Two words: stronger typing.

Re: Orthodox C++ (2016)

#136

You can take for (auto const & ess : esses) { ... } from my cold dead hands. Also, you can fight me if you want to take dynamic_cast (base_ptr) and force me to implement my own typing system every time I need to upcast. Basically, stick with C and leave C++ programmers alone. I haven't seen a less useful article about C++ in a long time, and as an HN reader, that's really saying something.

> for (auto const & ess : esses) { The problem with this is that whoever is reading the code as-is does not know what type "ess" is. Sometimes you get the definition somewhere nearby, in which case it is probably fine - assuming it is close enough that it'll be included in a diff - but more often than not you don't know. Yes, an IDE can probably tell you (probably, depends on the IDE and assuming everyone uses one) b…

C++ is an IDE type language in my opinion. C is not, because C doesn’t have an expressive enough type system anyway to justify it.

Yes, just use and IDE. This is a problem in Rust as well. And C#, Java, and others.

IMO you should use auto as much as possible. If the code can be written with auto, it should be. There’s no reason to repeat type definitions.

If you can use auto, what that means is the type is already statically known. C++ is a statically typed language; the compiler and tools know what type things are. So, just ask the tools, because they’re not wrong.

Re: Orthodox C++ (2016)

#137
post #25

Earlier quoted context omitted.

> y'know you can check if an operator has been overloaded And there lies the problem with C++: to be sure, you have to check. C++ code can't be taken at face value -- the most innocuous-looking code could be a ticking bomb.

My favorite was the regex engine that was implemented using C++ operator overloading. The author was very proud of it, but you could not tell what code was regex code and what code was math code. I went to some lengths with D to discourage such abusive operating overloading practice.

Thank you. I don't even use D, but appreciate all efforts to socialize sane programming practices.

Re: Orthodox C++ (2016)

#138
post #125

Earlier quoted context omitted.

> There are many more things to avoid than just iostream. But even "avoiding iostream" is stupid. The author presumably really means "avoid operator>> and operator<< for I/O". Even using type-safe printf-like stuff ultimately still sits on top of iostream.

doesn't require iostream.

fair, but it generates a std::string .. if you want to see it, what are you going to do with it? use .c_str() ??

Re: Orthodox C++ (2016)

#139
post #96
post #8

Earlier quoted context omitted.

One thing I've noticed about a lot of these "strict C" developers is that quite often they actually refuse to learn C++. One of the most common complaints of C developers regarding C++ is "it does things behind the scenes/performs magic", often with regards to operator overloading. When they refuse to actually look at the implementation (y'know you can check if an operator has been overloaded) AND they refuse to ackn…

I was programming in C++ before switching to C and I would say that C++ adds a huge amount of mental load compared to C. I think one can understand how much of a relieve it is to not worry about everything C++ does only after not using C++ for a quite a while.

Any time I go back to C from C++, it's only comfortable if I've got a C utility library that replaces most of std::

And that utility library (there are dozens of them) is just as subject to debate and issues as libstdc++

I am not going to implement my own C versions of 90% of the stuff std:: provides, sorry.

Re: Orthodox C++ (2016)

#140
post #7

I've developed a style that I legitimately call Heterodox C++ (mainly due to the popularity of Orthodox C++), it is effectively a purely functional & metaprogramming heavy style of C++. Quite the opposite of this, not everyones cup of tea, and it won't fit into every codebase but it is incredibly powerful. The template metaprogramming C++ offers is the most powerful of any imperative language, and (subjective opinion…

The problem with metaprogramming-heavy C++ codebases is always compilation times and obtuse error messages... Template metaprogramming is sometimes very useful to get around C++'s language restrictions, but I tend to use it sparingly.

I've been using C++ for about 20 years and I've yet to see these scary template error messages people always complain about. Yeah, they're long, but they contain all the information you need to fix the issue, which is damn near always at the deepest point in the call stack that you still control.
Post reply on HN