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.
Orthodox C++ (2016)
231–238 of 238 posts
Re: Orthodox C++ (2016)
#232Earlier 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…
Re: Orthodox C++ (2016)
#233You 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
Re: Orthodox C++ (2016)
#234Earlier 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)
Re: Orthodox C++ (2016)
#235Earlier 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…
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)
#236Earlier 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…
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)
#237Earlier 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,…
Re: Orthodox C++ (2016)
#238Earlier 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…
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.