I think it's worth being clear about a couple things. 1) This bug will definitely be fixed eventually. It's slightly embarrassing that it's been open for so long, but part of the reason for that is that 2) it's almost impossible to accidentally trigger this bug. The copy-pasted code is quite hard to follow, and I wouldn't be able to reproduce it from memory even if you paid me to try :) In contrast of course, the same mistake in C++ is one we all make the first week we learn about pointers.
Man somebody who does not understand Rust linked me this useless video. As far as I know the nextgen trait solver aka chalk should catch this bug. The reason why it happens and why nobody fixed it is because it's a design flaw which isn't easy to fix. Nobody obviously wants to write this in their code base. Rust is still winning in the end.
Sure. Thanks. But not everyone has your knowledge. Everybody is coming from a different knowledge base and understanding. We all pick up knowledge at different times and from different people. The more sources the better.🙄
Brilliant talk, thank you very much for sharing. Great production quality, learned loads of interesting stuff, and I'm inspired to to learn more. Very nice gilet as well!
The other talk I mentioned: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-dFIqNZ8VbRY.html The font is Berkeley Mono. The animations are all done in Keynote.
The best talk ever. Detailed explanation where it should be detailed and short when it needs to be short. 10/10. In a couple of years this talk will be a sensation. Bravo.
Don't want to be that person - but what specifically from this talk was about optimizing a high performance library? also please stop using high_resolution_clock
43:54 [slide 61] as long as we’re specifying some of the defaulted templates arguments - I’d comment that I’m very fond of using std::less<void> instead of std::less<T>.
That's fair. But I think `std::less<void>` has more to do with when you want to get heterogeneous comparison lookup out of the box. Otherwise `std::less<T>` is consistent with how it's currently defined in the standard for `std::map` (and `std::equal_to<T>` for `std::unordered_map`), and how it's defined in P0429 "A Standard `flat_map`" by Zach Laine (and in P1222 for `flat_set`).
41:17 [slide 57] another concern when choosing between std::map and flat_map is iterator-invalidation. Unlike flat_map - iterators to std::map (and std::unordered_map) stay valid if new elements are added or if other elements are erased. Great talk, Pavel!
Since flat map is an adaptor it _kinda_ inherits guarantees from the type it adapts. So yes, in case flat map adapts an `std::vector` (which is the default) iterators will be invalidated on insert/erase. But flat map can adapt a different sequence type with different guarantees, e.g. one which does not invalidate iterators and/or references on insert/erase, in which case they are not invalidated for flat map either.
It should be noted that these benchmarks are only useful for those that don't want to shop around for a better implementation nor are they willing to write their own. The real benchmark test is for a completely custom implementation which attempts to balance allocation strategies and take hints from the user on an estimate for the number of elements. The best general purpose allocation strategy that I've found for in-memory allocation is to double the capacity each time the memory grows. This means that the larger the container is the less often it will allocate and move the contents. However, there are times when you want to use more of a deque approach and again, it depends on the data being stored and how it's being accessed. I do find it funny that certain container types have taken this long to make it into the standard library because I've been using similar structures in my own code for decades now, but written in C. I've done a lot of experimentation with hash tables and as far as I've seen, the performance when implemented the correct way is better than the theorized performance whenever people show the big O notation. Also, I'm pretty sure the chart for insertion/removal into/from a vector is wrong. It should be O(M) as it depends on where the element is being inserted or removed. Only those elements that have a higher index will need to be moved if no allocations take place, and in cases where an allocation occurs all of them will need to be moved.
Great talk. In 49:45 note that if await_suspend() returns void (or true) the control is returned back to the “regular stack” (resumes the non-coroutine function on the top of this threads’ stack). The distinction is relevant for ‘symmetric transfer’ which Jonathan deliberately skipped, in which one coroutine can resume another, and if the latter suspends via void-returning in await_suspend we’ll not get to the caller-coroutine)
Thanks! Glad you enjoyed it Good note on the return value of await_suspend() and symmetric transfer -- it's a particularly neat feature of C++ coroutines. There was a very brief mention of resuming a different coroutine at 46:15, but unfortunately I didn't have the time to dig into it further
The vulnerability is caused by the users visiting certain pages directly in the browser and also the page not redirecting those visitors back to the pages they came from
Yes, I want to become a C++ Master too! From this day forward, I will devote myself to becoming a C++ Master as the primary directive of my life, to study C++ as if my life depends on it, because it really does, this is my career after all! I have a desire to deeply understand and learn C++ and related topics in programming. For that I am living an ascetic lifestyle, removing all distractions completely. Focusing only on my programming, no any extra things.
I liked this presentation very much, you should always strive to express yourself in code. Only that you blame iterators not supporting a semantic you added, i believe is questionable. But this were the means getting the audience attention. :) Thank you very much.
tl;dr: Views and ranges which remove and/or change the order of elements create ill defined borders if a classic iterator is used to point to the left or right of it (e.g. upper_bound()). Iterators should be separated into two distinct concepts: borders and elements. Elements can be nullable instead of .end(), borders are well defined and symmetric (begin() and end() reference-able) ... it sounds like a nice idea. There are some details to work out regarding how borders would be invalidated if the collection was mutated, but it sounds like a useful paradigm.
I identify so much with this topic as I've intentionally only ever bought low power hardware. I've never owned a discrete graphics card, for that matter. You're 100% correct when you say that not everyone has an ideal situation because even living in the best state in the US, I still get power outages here 5 or more times per year. It's the reason I have a UPS or two in every room in the house with electronic devices and why I recommend others do the same. As far as comparing against other languages, I personally prefer C to C++ and use it far more, and for nearly every personal project I've done I have chosen it. That said, I still also regularly use C++ and try to keep up to date with my knowledge of it. Part of why I would recommend that website you mention is because it tells you useful information such as when a given construct has been available as standard in the language, such as telling you "since C++11", but also it has an entire section for C as well. Towards C++, I would definitely agree that it, just like C and other system level compiled languages, allow you to optimize better than interpreted languages and for lower power hardware such languages are a must. I applaud the standard committee's efforts towards concepts like constexpr and consteval because they will definitely help in that regard and I applaud the work of compiler developers in implementing them. I would also argue that if you write idiomatic C++ that it is just as memory safe as other languages pretend to be and it is incumbent upon the developer to learn all of the tools and how to use them, such as open source software like `valgrind` which do a far better job than a program like `rustc` at analyzing memory usage and finding bugs. I used to hate C++ as a language, but the more new languages that kept popping up really made me appreciate so much more about it as a language. However, I will never stop adding a `using namespace std;` at the top of my C++ source files and eschew the ridiculous overuse of `std::` that so many developers do these days. Don't want name conflicts, don't use standard names in your own code.
Having made an attempt at implementing just the basic container types some 25-ish years back, I can tell you that you definitely don't want to start from scratch, especially in the current day. Also, I still say that std::map::operator[] shouldn't insert new keys. Implementing all of the C standard library was significantly easier back then, and even today is still significantly easier than the C++ standard library. If anyone is taking advice, unless you're willing to spend years on it, don't try to design and implement your own programming language, especially if you expect it to be a useful systems programming language. It is beyond annoying, although, from my own experience, consider using some sort of compiler construction tools or generating an IL such as what LLVM uses instead of writing the entire thing from scratch like an insane person.
36:39 By the way, in C++23 we also got std::basic_const_iterator which can potentially assist library developers implement their own containers and range adaptors. Great talk!
10:32 on slide 3.4 I think it might be better to use memcmp (or strncmp) to ensure that if the string implementation (that we’re testing) doesn’t put a null terminator (even if we planned for it to exist) we won’t hit UB. I guess this can get us down a rabbit hole - what if the data() member function has a bug and returns a dangling reference, etc. Great talk!
That's getting a bit into the weeds unnecessarily. The entire test centers around string literals, and if it's changed in the future to use something else you'll have to be capable of determining the length of whatever string type you use without also hitting UB.
Thanks for your comment! The issues you raise are indeed concerns. The null terminator issue will be caught by the unit tests for `basic_string::data`, as it's required to return a NUL-terminated pointer-to-char array (since C++11, and C++03 implementations also do this). The second issue you raised should be caught by sanitisers, fuzzing, and integration tests.