Meeting C++ is an independent platform for C++, supporting the C++ community by sharing news, blogs and events for C++. Details on the yearly Meeting C++ Conference can be found on the website meetingcpp.com
Update: Clang now identifies that the return value is 10! Funnily enough, if you don’t specify v.reserve(4), you still get an allocation, but the allocation is totally unused. It calls operator new, then operator delete, then returns 10.
I dont understand why would in C++ 14 std::is_artithmetic<char*>::value_type will be TRUE but for C++ 17 constexpr std::is_artithmetic<char*>::value_type = FALE ?
This was the most incredible c++ talk I’ve ever watched, thank you me bjorn fahller for providing this incredible information. This talk does not have many views right now, but it covers probably one of the most advanced c++ topics, this is pure computer science at its finest.
Pleasure to watch this video, I Get a pointer to move forward But request you to if You provide step by step procedure of installation and build of both grpc and proto file in both window and linux os. It would be more appreciated!
I think that the memory leak is not the main problem here: Initial State * Before emplace_back() * v is an empty std::vector<V>. * Internal pointers (begin, end, end_store) are nullptr. After emplace_back() * v.emplace_back(); * Adds a default-constructed V object (v_inner) to the vector v. * The internal pointers of v are updated to point to the allocated storage: * begin: Points to v_inner. * end: Points to one past v_inner. * end_store: Points to the end of the allocated storage. * v_inner itself is an empty std::vector, so its pointers (begin, end, end_store) are nullptr. After swap(v.front()) * v.swap(v.front()); * Swaps the contents of v with v_inner. * The internal pointers after the swap: * Original v (now an empty vector): * begin: nullptr * end: nullptr * end_store: nullptr * New v_inner (contains the original v's data): * begin: Points to the original v's first element (which is v_inner). * end: Points to one past the original v's last element. * end_store: Points to the end of the allocated storage of the original v. Destruction Sequence When main() Exits * The original v goes out of scope, and its destructor is called. * Since v's internal pointers are nullptr, it has no allocated memory to deallocate. When v_inner Goes Out of Scope * Destruction of v_inner: * The destructor of v_inner is called. * It starts destroying its elements, which now includes itself due to the swap. * Self-Referential Destruction: * v_inner.begin() points to v_inner. * Destroying v_inner triggers its own destructor again, leading to recursive destruction calls. Issues 1. Recursive Destructor Calls: * The recursive calls can lead to a stack overflow and undefined behavior. * This creates a problematic scenario where the destructor keeps calling itself. 2. Memory Leak: * Since v's memory was not deallocated when it went out of scope (because its pointers were nullptr), the memory originally allocated for v remains allocated but unmanaged.
One of the biggest problems I've found with OOP is that it distributes the complexity of business requirements into relatively few and interdependent objects/abstractions. That has a tendency to lack orthogonality and skyrocket the complexity of the existing abstractions as well as multiply the coupling between them. Consider a design requirement like this from the AD&D rulebook: >> Nystul's Magic Aura : By means of this spell any one item of a weight of 50 g.p. per level of experience of the spell caster can be given an aura which will be noticed if detection of magic is exercised upon the object. If the object bearing the Nystul's Magic Aura is actually held by the creature detecting for a Dweomer, he, she or it is entitled to a saving throw versus magic, and if this throw is successful, the creature knows that the aura has been placed to mislead the unwary. Otherwise, the aura is simply magical, but no amount of testing will reveal what the magic is. The component for this spell is a small square of silk which must be passed over the object to bear the aura. Unless we've anticipated a whole lot in advance, implementing just this one new rule into even the most carefully-designed OO architecture will likely require changing and adding to the complexity of existing designs/interfaces/abstractions, and this is just one design requirement out of a 300+ page book filled with loads of such requirements. When we implement such design requirements procedurally or functionally, we get the desired orthogonality and don't have to add to the complexity of any design that already exists. We can just add a new function to implement each new such requirement, and distribute all the complexity into something new rather than things that already exist. OO veterans tend to wholeheartedly agree that OO design demands careful anticipation of the full design requirements upfront. What I think they fail to realize is how poorly this speaks of the OO paradigm when we use it as the central design paradigm for our business requirements, and how impossible it is to meet this demand in large-scale, long-lived software whose business requirements are ever-changing with each new version. I do find OOP useful on the small scale for relatively small sections of a codebase, since there are usually sections of a codebase whose design requirements can be trivially guaranteed to never change. Yet I think people moving away from OOP as the primary design paradigm -- not entirely and not dogmatically -- towards the likes of functional programming are genuinely doing it for very legitimate reasons (ex: John Carmack, who is a very mature sage of a programmer and not merely a cool kid), and there are radically simpler, more flexible, easier-to-maintain, easier-to-test, thread-safe codebases wanting to emerge when we do so.
Dear Rainer, you are such an inspiring person, I've learned so much from your excellent talks, blogs and books! I wish you all the best and hope you get better soon.
I think there is a flaw with this design. Since the spmc queue supports variable-length messages, if a consumer is lapped by the consumer, the mVersion field the consumer thinks it is spinning on is probably not the version counter field at all. It may well be spinning on some random bytes right in the middle of mData. Then if the random bytes happen to be the version of the consumer is expecting(although the probability is very low), it could be disastrous. The customer does not know it is lapped at all, and continue processing with the meaningless data.
What ends up happening is that people explain the easy stuff with very simple clear language and they really break it down. But with the advanced stuff they prefer to believe you already know everything. I've been able to use Make to make compilation easier but CMake is really complex. It looks like it's got it's own language. A basic tutorial might include using CMake to write hello world then have it compile a very basic C hello world project with minimal Cmake files
Yes, CMake is complex. I personally favor using a generator to get the project started and did a talk about this in spring: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-3KlLGNo5bn0.html
*Abstract* This video explores C++20's coroutines, comparing them to traditional functions and highlighting their unique ability to preserve state and be resumed. The speaker delves into the key components of coroutines, including the promise type, awaiter type, and iterator, showcasing their customization potential. Through practical examples like interleaving data streams and task scheduling, the video demonstrates the power of coroutines in simplifying code and achieving efficient concurrency. *Speaker Introduction* * *0:00* Andreas Fertig, a C++ trainer and consultant, introduces himself and the topic of his talk: C++20 coroutines for beginners. * *0:37* Fertig explains the meaning and origin of his last name, highlighting the challenges of spellcheckers recognizing it as a proper noun. *Understanding Coroutines* * *2:35* Fertig differentiates coroutines from traditional functions by emphasizing the ability of coroutines to be resumed and preserve their state through `co_yield`, `co_await`, and `co_return` keywords. * *3:00* He illustrates the control flow of functions and coroutines, showcasing the resumable nature of the latter. * *6:14* He clarifies that coroutines are a superset of functions, with functions being a specialization of coroutines that do not pause. * *7:21* Fertig explains the distinction between stackful and stackless coroutines, noting that C++ implements stackless coroutines where state is stored on the heap. * *8:39* He introduces the concept of cooperative multitasking, where threads decide when to yield control, contrasting it with preemptive multitasking used in `std::thread`. *Coroutine Elements and Customization* * *11:50* Fertig details the key elements of a C++ coroutine: the return type (awaiter type), the promise type, the awaitable type (optional), and the iterator (optional). * *13:32* He emphasizes the role of the promise type in customizing coroutine behavior through various customization points like `get_return_object`, `initial_suspend`, `yield_value`, `await_transform`, `final_suspend`, and `return_value`. *Coroutine Examples* * *17:56* *Example: A Basic Chat Coroutine:* Fertig showcases a simple chat coroutine demonstrating the use of `co_yield`, `co_await`, and `co_return`, along with the implementation of the promise and return types. * *35:19* *Example: Interleaving Data with Coroutines:* He presents a coroutine that interleaves elements from two `std::vector` objects, highlighting the use of an iterator to enable range-based for loops for more readable code. * *46:12* *Example: Cooperative Task Scheduling:* Fertig demonstrates a coroutine-based scheduler that manages multiple tasks cooperatively, contrasting it with preemptive multitasking using threads. *Coroutine Restrictions and Limitations* * *56:21* Fertig outlines several restrictions on coroutines, including their incompatibility with `constexpr`, `consteval`, constructors, destructors, `varargs`, plain `auto` return types, concept return types, and the `main` function. *Q&A Session* * *1:00:01* *C++23 and Coroutines:* The discussion touches upon the `std::generator` introduced in C++23, its limitations, and the challenges of creating a universal library type for coroutines due to their flexibility. * *1:02:06* *Parallelism and Coroutines:* Fertig clarifies that coroutines do not inherently run in parallel but offer efficient concurrency through cooperative multitasking. He emphasizes the possibility of combining coroutines with `std::thread` for more complex scenarios. * *1:03:56* *Coroutine Depth and Heap Usage:* He confirms that the depth of coroutine chains is practically limited only by available heap memory. * *1:07:51* *Coroutine Preemption:* Fertig reiterates that coroutines are not preemptible and require careful design to avoid long-running tasks that block other coroutines. * *1:08:47* *Coroutines and Boost.Asio:* He suggests that the upcoming C++26 `sender/receiver` feature might be a better fit for Boost.Asio integration than coroutines. * *1:16:05* *Typical Use Cases:* Fertig highlights callback replacement and event handling as common scenarios where coroutines excel. * *1:21:04* *Coroutines in Embedded Systems:* He clarifies that coroutines do not require special OS support, making them suitable for embedded systems with limited resources. The primary requirement is heap access for storing coroutine state. * *1:23:12* *Stackful Coroutines in C++:* Fertig acknowledges the possibility of introducing stackful coroutines in the future if their benefits are clearly demonstrated. * *1:23:51* *Allocator Awareness:* While coroutines are not directly allocator-aware, they can utilize custom allocators through overloading `operator new` and `operator delete` in the promise type. i used gemini 1.5 pro Token count 19,459 / 1,048,576
So, adding new draw or serialize overloads for new ShapeConcepts just really needed? Maybe it should also be included to implementation details of the Shape with a templated version.
36:07 I may be mistaken, but I think currently such reinterpret_cast from buffer.data() is technically an UB unless std::launder() is used. Technically, because apparently popular compilers don't require std::launder() in this case. See P3006R0 "Launder less".
@@MeetingCPP this is the same thing every cpp person says.... like by and large cpp is much less popular than the current web dev languages. C# Java and Javascript dominate the market... yes you can still be a devils advocate.. but it's such a cop out to say "well it depends on location.." nowhere in the USA is cpp being used than any of the above languages. I am talking about the entire industry, not just the handpicked ones where cpp is used
37:05 - Interesting Example. I taught my students that in C# the Random class actually took the time, so in order to make it work you need to initialize an instance and reuse the same instance. Or else you'll be getting bugs because it generates the same number.
Write a thick client, write your own serializers, implement custom schema publishing... Hmm, I wonder what features from gRPC are actually there after all this and what is even the point of using such a heavy-duty library in this context. And yes, I am genuinely curious.
*Abstract* This presentation explores gRPC, a modern Remote Procedure Call (RPC) framework designed for high-performance distributed systems. It begins with an overview of gRPC's features, including cross-platform support, load balancing, and authentication. The presentation then delves into Protobuf, the language-neutral serialization mechanism commonly used with gRPC. The core of the presentation covers both the standard approach to using gRPC and a novel alternative. The standard approach involves defining services in `.proto` files, generating code, and directly using gRPC's service APIs. The alternative approach introduces a custom library called 'mygrpc,' which wraps gRPC and Protobuf. This library simplifies development by: * *Hiding gRPC and Protobuf Internals:* Users interact with custom APIs, not raw gRPC or Protobuf. * *Providing Generic Services:* A single generic service definition replaces complex `.proto` files. * *Streamlining RPC Calls:* The library handles reactors, message chunking, and data serialization. The presentation concludes with a summary of the benefits and drawbacks of this alternative approach, noting increased flexibility and cleaner code, but also the overhead of maintaining custom serializers. *Keywords:* gRPC, Protobuf, RPC, Remote Procedure Calls, distributed systems, serialization, C++
Defining operator == is still useful when also defining operator <=> because operator == (and operator !=) can return early when 2 containers don't have the same size.
Hah, what a coincidence! Early this month i JUST gave a talk on FOSDEM about the internal workings of GDB's inbuilt time travel debugging and how we're taking baby steps in improving it On an interesting note, the hardware watchpoint was fixed recently, and will no longe be a bug in GDB 15 :)
Ubuntu 20.04 has some different configuration which makes following this example very difficult. I didn't get the same crash reason the presenter got. Ubuntu 20.04 has some stack protection. "*** stack smashing detected ***: terminated"
With all due respect , following-up the other comments, it might look like there are some old-school developers a bit grumpy to have to learn stuff. Regarding the logic of the talk, I can’t follow along why (1) begin MUST be O(1) generally, even more when taking into that there was something special with fwdlist before ranges already, (2) why begin in a view must have the same semantics than in a container. In other words, if one is applying a filter to a collection and then surprised that it needs to iterate through it… 🤷🏻♂️ In any case, excellent talk from Nico as usual, top learning material. It is essential to make these parts also visible and talk about them.
noone said begin() must be O(1), or I maybe missed it. As I understand it was pointed out that is was 'amortized constant' due to caching, but in practice, in 99.x% of cases, begin() will only be called once and for those usecases, it will be linear. So the issue here is that amortized constant is a bit 'marketing style sale talk' and can be misleading in practice, and there is the long standing convention to not provide operations that are bad performance, but not providing begin() would render views unusable, so we have to have the begin() and we have to learn it can be more costly, ok, no real problem, but making the language again a bit more complex to learn. Also I have missed that a view must have the same semantics, again as I understand the complexity of the language increases, ok, no real problem, deal with it. The actual issues with filter view are summarized at 56:43, where I agree those are very very annoying.
Abstract: Test-Driven Development (TDD) has been acknowledged for its effectiveness in reducing development time and error rates, leading to widespread adoption in many C++ projects. However, its application in embedded C++ development, especially those involving microcontrollers with significant hardware dependence, presents unique challenges. At the Meeting C++ 2023, Daniel Penning addresses the obstacles and opportunities for integrating TDD in microcontroller-based development. The talk delves into the dual-target approach, advocated by James Grenning, which recommends running unit tests both on microcontrollers (On Target) and personal computers (Off Target). Despite its advantages, this method reveals limitations when dealing with hardware-related code such as drivers. Penning introduces open loop testing to complement dual targeting, an innovative method where external microcontroller interfaces are mimicked using mocks and stubs. This methodology facilitates a practical TDD workflow that enables developers to reap the full benefits of TDD in their microcontroller development process. The talk not only illustrates how the dual-target approach can be built using open source solutions but also compares the additional advantages provided by commercial alternatives. It also touches upon the significance of TDD in embedded development, emphasizing the need for quick, automated feedback loops essential for TDD efficacy. Demonstrations within the presentation showcase the implementation of open loop testing, using a Robot Framework to script tests at the pin level for direct hardware interaction. Penning provides a thorough analysis of the nuances in off-target and on-target testing, detailing their respective limitations and how open loop testing fills the gaps for a comprehensive TDD practice. Finally, the session concludes with an insightful Q&A that explores related topics such as hardware verification, functional safety, and integration testing, and discusses industry trends in hardware abstraction layer and driver development. This presentation serves as a crucial guide for software engineers and project managers in embedded systems looking to refine their development practices with TDD, improving their product quality and reliability in a domain where traditional testing methods often fall short. Chapter Titles I. Fundamentals of TDD in Embedded Systems - 00:00 Introduction to TDD and Embedded Software Development - 01:59 The Importance and Challenges of TDD in Embedded Systems II. Testing Strategies for Embedded Software - 04:22 Testing Embedded Software Off-Target vs. On-Target - 07:26 Establishing Off Target Testing in Embedded Development - 11:41 Limitations and Risks of Off Target Testing - 14:33 Testing Hardware Dependent Code - 15:34 On Target Testing III. Advanced Testing Techniques and Tools - 17:09 State-of-the-Art in Testing: Pin Behavior - 19:13 Challenges with Manual and Register-Based Testing - 25:06 Open Loop Testing: A New Approach - 28:00 Demonstration of Open Loop Testing IV. Practical Application and Case Studies - 31:09 Configuration and Initial Test - 33:10 Multiple Byte Reception and Hardware Interaction - 35:19 Implementation Adjustments and Debugging V. Summation and Addressing Complex Testing Scenarios - 39:01 Summary and QA Session - 45:12 Concerning Emulation and Real-Time Testing - 47:50 Challenges in Hardware Verification VI. Ensuring Functional Safety and System Integration - 48:35 Functional Safety and Testing Approaches - 50:15 Integration Testing and Developer Feedback - 51:34 Hardware Abstraction Layer and Driver Development VII. Closing Remarks - 53:15 Conclusion
Depressing is the only way to describe this. We've waited so long for ranges because they would make it so much harder to make programming errors, and instead they've gone and made it more likely to make errors. It's a shame they didn't make the easy case easy and the complex case possible and instead made the easy (common) case hard and the complex (rare) case easy. The only safe way to teach this is the simple "don't use ranges", which sucks.