Live data from Hacker News

Orthodox C++ (2016)

bkaradzic.github.io

231–238 of 238 posts

Re: Orthodox C++ (2016)

#231
post #179
post #173

Earlier quoted context omitted.

Not really, given that GCC no longer compiles with a pure C compiler. Unless of course, you don't have anything to do, and feel like bootstraping GCC 16, using a compiler chain all the way back to 2012 thereabouts.

The question is whether GCC is a good example of the benefits of C++ for compilers. Considering the code looks to 95% like C code and uses data structures that we originally implemented in C, I don't see this argument.

I told him the same thing multiple times, just open a random code location in GCC, or a recently committed change, and see that it's basically C. But he keeps repeating that ridiculous argument like a broken record.

Re: Orthodox C++ (2016)

#232

Earlier quoted context omitted.

> It is not a chunk list, like many (including me) seem to have assumed. The thing C++ programmers tend to expect (though perhaps not you) is Rust's std::collections::VecDeque - the growable array type again but used as backing for a ring buffer. This type has amortized O(1) push and pop at both ends, I assume since you didn't like the amortized growth of Vec / std::vector you'll feel the same way but that's what mos…

I don't know the size up front because it goes up and down depending on load. I want to be able to buffer jitters/spikes but not hog memory when there is no data in the queue. I was assuming it's natural to want a simple linked list of chunks to represent this, maybe chunks can be partially full here. So chunk -> chunk -> chunk, and each chunk is actually a node with a buffer pointer + size + fill fields, or maybe th…

[flagged]

Re: Orthodox C++ (2016)

#233

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.

Implementing STL iterators are a bloody PITA

std::range fixes this

Re: Orthodox C++ (2016)

#234

Earlier quoted context omitted.

Implementing STL iterators are a bloody PITA

You don't need iterators for the range-based for loop, just a .begin() and .end() method which returns a raw pointer is enough. E.g.: https://github.com/floooh/oryol/blob/eb08cffe1b1cb6b05ed14ec... (don't use that project though because it's been archived, I've switched back to plain old C in the meantime)

If it's a contiguous array, then sure.

Re: Orthodox C++ (2016)

#235

Earlier quoted context omitted.

> It is not a chunk list, like many (including me) seem to have assumed. The thing C++ programmers tend to expect (though perhaps not you) is Rust's std::collections::VecDeque - the growable array type again but used as backing for a ring buffer. This type has amortized O(1) push and pop at both ends, I assume since you didn't like the amortized growth of Vec / std::vector you'll feel the same way but that's what mos…

I don't know the size up front because it goes up and down depending on load. I want to be able to buffer jitters/spikes but not hog memory when there is no data in the queue. I was assuming it's natural to want a simple linked list of chunks to represent this, maybe chunks can be partially full here. So chunk -> chunk -> chunk, and each chunk is actually a node with a buffer pointer + size + fill fields, or maybe th…

> I was assuming it's natural to want a simple linked list of chunks

In the 1970s or 1980s that does feel entirely natural, but in the 1990s the 68040 and i486 both introduce L1 data cache and so now all list chasing hurts very badly, your structure is a list chase any time we index into the collection.

I think I can see a way to have what you're describing hit amortized O(1) push/ pop with the spikes which are amortized being more frequent (linear with capacity) but fixed size and smaller (allocate or free one block then do some housekeeping), it costs more RAM because of the block overhead and it is no longer contiguous, but I see that for your intended application you probably don't care about either problem.

Now that I think I understand your data structure better it's much less similar to std::deque than I had originally thought, it does seem very niche to me, but more power to you if you write such a type.

Re: Orthodox C++ (2016)

#236

Earlier quoted context omitted.

I don't know the size up front because it goes up and down depending on load. I want to be able to buffer jitters/spikes but not hog memory when there is no data in the queue. I was assuming it's natural to want a simple linked list of chunks to represent this, maybe chunks can be partially full here. So chunk -> chunk -> chunk, and each chunk is actually a node with a buffer pointer + size + fill fields, or maybe th…

> I was assuming it's natural to want a simple linked list of chunks In the 1970s or 1980s that does feel entirely natural, but in the 1990s the 68040 and i486 both introduce L1 data cache and so now all list chasing hurts very badly, your structure is a list chase any time we index into the collection. I think I can see a way to have what you're describing hit amortized O(1) push/ pop with the spikes which are amort…

Yes, I am talking about a buffer for an outbound queue that should buffer on the order of MB/sec. That's decidedly not a niche thing. It's very basic systems engineering (and also how socket buffers are represented in a kernel for example).

You would chunk this at a reasonable size, at least multiple kilobytes per chunk. That is not slow, it is basically the only way to do it. Yes, that is amortized, bounded overhead. Sure it costs a bit of extra RAM, like one extra pointer and maybe 1-2 integers per chunk? For chunks of 4 KB, this overhead is predictably less than 1 % plus less than 1 chunk worth of fragmentation in the last chunk. That is NOT unpredictable spikes of > 100 percent during reallocation or 100000 percent due to low utilisation...

I believe you can even instruct the CPU to preload the next buffer while still streaming the last, but personally have never had the need to dive _that_ deep. It would probably be very hard to measure any performance benefit from doing so. I like to write very basic straightforward C code, just solve the data structure problem first, not hand-wave it.

Re: Orthodox C++ (2016)

#237
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,…

Not really apropos any of this but a vivid career memory for me is leaving a startup that was all in C++ and going to Arbor Networks, which was all C, and porting the STLport map to rbtree.c and making it our default container. No, I have no idea why I did that. Different times!

Re: Orthodox C++ (2016)

#238

Earlier quoted context omitted.

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 st…

> Yes, just use and IDE The best the IDE can do is display a tooltip or something like that which is cumbersome when reading the code because you need to move over everything to figure out what the types are. And sometimes for whatever reason even that fails. And this is only useful in the context of using an IDE: code can be found outside IDEs too, even if all you do is use an IDE for your development (not everyone…

Many IDEs I’ve seen include the type in-line. No tooltip or anything.

I’ve also never seen that fail, because again, C++ is statically typed. When you say “auto” you’re not saying “any type”. No, it has a type, and the compiler has to know it, otherwise auto doesn’t work.

As for patches and whatnot, I still don’t think it matters. CI/CD will catch it 100% of the time because C++ is statically typed. If you want to read a patch in PLAINTEXT in an email or some bullshit, then whatever. I think nobody is actually doing that because they at least want syntax highlighting, no? So we’re right back at IDE.

Post reply on HN