CppCon, The C++ Conference 2025 Sergey Dobychin: "Constexpr STL Containers: Why C++20 Still Falls Short" youtu.be/Py4GJaCHwkA One of the most powerful features that sets C++ apart from many other languages is its ability to perform complex constant evaluation at compile time using constexpr. With each new language standard, these capabilities have expanded — and C++20 took a big step forward by allowing dynamic memory allocation in constexpr functions via operator new. This made it possible, for example, to use containers like std::vector and std::string in constexpr code. However, there’s still a key limitation: you can only use these containers in constexpr functions — not as top-level constexpr objects. That means you can't declare a constexpr std::vector or std::string at global scope and use it later in runtime without overhead for initialization. The language still doesn’t fully support top-level dynamic containers in constant expressions. In this talk, I’ll explore the current state of constant evaluation in modern C++, with a special focus on dynamic memory allocation in constexpr contexts. I’ll walk through the limitations in C++20 and show how you can go beyond them by implementing a custom allocator that enables truly compile-time std::vector, std::string, and other STL containers, which will become fully supported as constexpr in future standards, thus opening the door to more powerful and flexible compile-time programming. --- Sergey Dobychin Sergey worked in systems programming at Kaspersky Lab. Currently, he is developing desktop applications in C++.
CppCon 2025 Sergey Dobychin Constexpr STL Containers Limitations
More Relevant Posts
-
CppCon, The C++ Conference 2025 - Andrei Zissu: "How to Build Type Traits in C++ Without Compiler Intrinsics Using Static Reflection" youtu.be/EcqiwhxKZ4g Type traits are a powerful feature of C++ that allows programmers to query and manipulate the properties of types at compile time. They are widely used in generic programming and metaprogramming to enable static polymorphism, type-based dispatching, and compile-time optimization. However, not all type traits can be implemented using the C++ language alone. Some type traits, such as std::is_class, require special support from the compiler in the form of compiler intrinsics or built-ins. These intrinsics are non-portable functions or variables that are recognized and handled by the compiler directly, rather than being defined in a library. In this talk, we will have a quick overview of the current state of type traits and of static reflection in C++. We will then see how these two worlds can join forces to give us a superior portable product, which no longer requires the use of compiler intrinsics. We will conclude by discussing a possible future where compiler and library are not necessarily mutually dependent, affording any C++ project greater freedom of choice. --- Andrei Zissu Andrei Zissu is a veteran cross-industry C++ developer, notably having worked on low-level reverse engineering systems employing API hooking, DLL injection and other advanced techniques. He has been a member of the WG21 C++ Standards Committee since early 2022, and as such is actively involved in the contracts study group (SG21) and is also keeping a keen eye on reflection work in SG7. He is currently employed as Windows Tech Lead at Morphisec, a revolutionary Israeli cybersecurity company.
How to Build Type Traits in C++ Without Compiler Intrinsics Using Static Reflection - Andrei Zissu
https://www.youtube.com/
To view or add a comment, sign in
-
Mutex might sound like the solution here, but you also essentially lose the parallelism by making the thread wait for other threads to finish work. Things LIKE atomics should be considered the defacto answer, mutexes are a last resort.
Debugging a Race Condition in C++ While working on a multithreaded module, I encountered an unexpected issue. Even though the logic looked correct, the final output was inconsistent every time. Problem: Multiple threads were updating a shared variable without synchronization. Expected: 200000 Actual: Random incorrect values After debugging, I found the root cause: Race Condition due to non-atomic operation (counter++) Key Learning: In multithreading, even a simple increment operation is not safe. It involves: Read → Modify → Write When multiple threads execute this simultaneously, data gets corrupted. Solution: Used mutex to synchronize access to shared resource. Also improved code using: lock_guard<mutex> for better safety and readability. Takeaway: Never trust shared data in multithreaded environments without proper synchronization. #cpp #multithreading #racecondition #concurrency #debugging
To view or add a comment, sign in
-
-
C++26 is here, and it’s a game changer! The latest C++ standard is officially finalized, and it’s packed with features that make the language safer and more powerful. If you’ve been waiting for less boilerplate and better performance, this is for you. Key highlights include: 🔹 Static Reflection: Finally, the ability to inspect types at compile-time! 🔹 Contract Programming: Built-in preconditions and postconditions for safer code. 🔹 Linear Algebra Library: Native support for high-performance math. 🔹 #embed: A much simpler way to include binary data in your projects. C++ continues to evolve, proving it’s still the backbone of high-performance software. Check out the full list of features here: cppreference.com #Cpp26 #Programming #SoftwareDevelopment #Coding #CPP #TechUpdates https://lnkd.in/gbe6RqHh
To view or add a comment, sign in
-
𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰𝘆 𝗶𝗻 𝗖++ 𝗯𝘆 𝗙𝗲𝗱𝗼𝗿 𝗚 𝗣𝗶𝗸𝘂𝘀 At CppCon 2022, Fedor G. Pikus delivered one of the most comprehensive overviews of C++ concurrency that I have seen: "Concurrency in C++: A Programmer's Overview." 𝗕𝗲𝗳𝗼𝗿𝗲 𝗖++𝟭𝟭, 𝘄𝗲 𝘄𝗲𝗿𝗲 𝗳𝗹𝘆𝗶𝗻𝗴 𝗯𝗹𝗶𝗻𝗱. Pre-C++11 code relied on POSIX or Win32 conventions, rather than the language itself. Because the compiler had no concept of threads, it was free to hoist operations out of "locked" regions. What saved us? Compilers that voluntarily obeyed external standards. You don't want to build on that foundation. 𝗧𝗵𝗲 𝗿𝗲𝗮𝗹 𝗴𝗶𝗳𝘁 𝗼𝗳 𝗖++𝟭𝟭 𝘄𝗮𝘀𝗻'𝘁 𝗷𝘂𝘀𝘁 𝘀𝘁𝗱::𝘁𝗵𝗿𝗲𝗮𝗱 — 𝗶𝘁 𝘄𝗮𝘀 𝘁𝗵𝗲 𝗺𝗲𝗺𝗼𝗿𝘆 𝗺𝗼𝗱𝗲𝗹. C++11 formally defined how threads interact with memory. It ensures that accessing different memory locations from various threads is always safe. It also clarifies exactly when undefined behavior occurs (i.e., concurrent reads and writes to the same location). This provided us with a shared vocabulary to reason about concurrency, which is as important as the primitives themselves. 𝗧𝗵𝗿𝗲𝗮𝗱𝘀 𝗮𝗿𝗲 𝗲𝘅𝗽𝗲𝗻𝘀𝗶𝘃𝗲. 𝗨𝘀𝗲 𝘁𝗵𝗲𝗺 𝘄𝗶𝘀𝗲𝗹𝘆. Pikus measured thread startup latency at ~0.1 ms and join latency at ~0.2 ms. That equates to hundreds of thousands of potential CPU instructions. Short computations don't belong in dedicated threads. The correct approach is to maintain a small, long-lived thread pool and feed it tasks instead of creating threads for each computation. 𝘀𝘁𝗱::𝗮𝘀𝘆𝗻𝗰 𝗶𝘀 𝗻𝗼𝘁 𝘆𝗼𝘂𝗿 𝗳𝗿𝗶𝗲𝗻𝗱 𝗳𝗼𝗿 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲. In practice, implementations either serialize work or spawn an unlimited number of threads. Until the standard incorporates executors, use a proven library (TBB, etc.) for real workloads. 𝗖++𝟮𝟬 𝗳𝗶𝗹𝗹𝗲𝗱 𝗺𝗲𝗮𝗻𝗶𝗻𝗴𝗳𝘂𝗹 𝗴𝗮𝗽𝘀: 🔹std::latch and std::barrier for thread synchronization points 🔹std::semaphore for resource counting 🔹std::jthread for automatic joining 🔹Coroutines for async programming 𝘁𝗵𝗿𝗲𝗮𝗱_𝗹𝗼𝗰𝗮𝗹 𝗶𝘀 𝗮𝗻 𝘂𝗻𝗱𝗲𝗿𝘂𝘀𝗲𝗱 𝗴𝗲𝗺. With per-thread storage, you can eliminate locks entirely on hot paths. Simply aggregate the results at the end. 💡 The deeper message of this talk is that the C++ memory model is more than just plumbing. Rather, it's a contract between you, the compiler, and the hardware. Understanding this contract can transform your concurrent code from "seems to work" to "provably correct." 𝗥𝗲𝗳𝗲𝗿𝗲𝗻𝗰𝗲𝘀 🎥 Fedor G Pikus, "Concurrency in C++: A Programmer’s Overview (part 1)", CppNow 2022, 22 Jul 2022, https://lnkd.in/dcP5-K7H 🎥 Fedor G Pikus, "Concurrency in C++: A Programmer’s Overview (part 2)", CppNow 2022, 22 Jul 2022, https://lnkd.in/dgHuM8i7 #CPlusPlus #CppCon #Concurrency #SystemsProgramming #SoftwareOptimization
Concurrency in C++: A Programmer’s Overview (part 2 of 2) - Fedor Pikus - CppNow 2022
https://www.youtube.com/
To view or add a comment, sign in
-
Check out my comparison of approaches to checking if a character is valid for a given encoding. I discuss a naive and an optimised approach in both C and assembly; and also lament the compiler. https://gist. github. com/sunny73cr/bc652f205dee713983a4df9d37febbe3
To view or add a comment, sign in
-
CppCon, The C++ Conference 2025 - Closing Keynote 🖥️ Matt Godbolt: "C++: Some Assembly Required" youtu.be/zoYT7R94S3c --- Join Matt in exploring how the C++ ecosystem has evolved through the interplay of intentional design and emergent collaboration. Standards committees craft language features and compiler teams implement them, but something amazing happens in the spaces between: tools appear, communities form, and solutions emerge that nobody quite planned for. What started as individual developers solving their own problems has grown into an interconnected ecosystem that shapes how we all write C++. From documentation to testing, from build systems to package managers, we'll examine how the C++ community has assembled itself around shared pain points and accidental standards. Using examples and perhaps too many rainforest metaphors, this talk celebrates not just the language we've built, but the organic ecosystem that's grown up around it. Come discover why C++'s greatest strength might be that it's always required some assembly. --- Matt Godbolt Matt Godbolt is the creator of the Compiler Explorer website. He is passionate about writing efficient code. He has previously worked at a trading firm, on mobile apps at Google, run his own C++ tools company and spent more than a decade making console games. When he's not hacking on Compiler Explorer, Matt enjoys writing emulators for old 8-bit computer hardware.
C++: Some Assembly Required - Matt Godbolt - CppCon 2025
https://www.youtube.com/
To view or add a comment, sign in
-
Did you ever wonder how RTOS is written? I might have a gift for you. If you want to write an OS kernel, then there's no help. You have to write one yourself. If you were just curious about what's inside, then digging in codebases of even small RTOSes may be overwhelming. These systems do a lot of different tasks and their codebase is optimized for speed, not for readability. Even CMRX codebase needs fair amount of learning because you know what is where (and why). In reality, the "juicy stuff" that makes OS kernel an OS kernel is barely more than few functions. The rest of the kernel? Mostly CRUD application. The biggest difference in programming is that you can't use mutexes, because you provide them. You have to synchronize some other way. If you were ever interested in how to put an OS kernel together but didn't want to crunch through large codebases, then check link in comments. There lies almost the smallest possible code that has right to call itself kernel.
To view or add a comment, sign in
-
-
Hi folks, I was building a personal project this weekend and ended up using a lot of smart pointers in C++. Ive noticed that many people find them confusing at first, so here’s a simple way I think about them: 1. std::unique_ptr Use this when there is clear, single ownership. The object’s lifetime is tied to one owner, and ownership can be transferred using std::move. 2. std::shared_ptr Use this when multiple parts of your system need to share ownership of an object. The object lives until the last reference is released, preventing premature deletion. Be careful though cyclic references can lead to memory leaks. 3. std::weak_ptr A non-owning reference to an object managed by shared_ptr. It does not affect the object’s lifetime and is mainly used to break cyclic dependencies. Still exploring more real-world patterns around this. Would love to hear how others approach this. #cpp #multithreading #systemsprogramming
To view or add a comment, sign in
-
🚀 uint32_t vs unsigned int — What’s the difference? If you're writing embedded code, knowing the difference is important. Here’s a simple breakdown 👇 🔹 uint32_t → Defined in "stdint.h" and always 32-bit 🔹 unsigned int → Built-in C type, size can depend on compiler 💡 Simple rule: Need exact 32 bits? Use uint32_t General use? unsigned int can work. ✅ Use uint32_t for: - Registers - CAN/SPI/UART data - Portable code ✅ Use unsigned int for: - Counters - General variables ⚠️ When size matters → use uint32_t Small difference… but important in embedded C. #EmbeddedSystems #CProgramming #Firmware #STM32 #EmbeddedC
To view or add a comment, sign in
-
“Multithreading isn’t about spawning more threads—it’s about orchestrating work efficiently. A thread pool doesn’t increase threads; it eliminates chaos.” C++ Thread Pool Guide https://lnkd.in/gWp8mdra #threading #c++ #threadpool
To view or add a comment, sign in
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development