Welcome to SwedenCpp
Latest blogs, videos, podcasts and releases in one stream
Friday, October 2, 2026
SPL - Open Source, Constexpr Library for Composing Algorithms - John Bandela - C++Now 2026🎥CppNow
Short-Circuit: When A Is False, B Must Not Run #coding #development #programminglanguage #cpp🎥PVS-Studio
Is C++ safety a skill issue or a language problem🎥MeetingCpp
C++ Lambdas Are Secretly Structs: The Overloaded Trick #coding #ddev #programminglanguages #cpp🎥PVS-Studio
Hello World, but it gets increasingly more cursed 💀 #Shorts🎥DeepDiveDev
Lets explore the stack📝Meeting C++ blog
Distribution Strategies for Indie Audio Developers - From Plugin to Product - Dani Karanyi🎥audiodevcon
Go vet can't go: How to create your own Go analyzer?🎥PVS-Studio
Why Rust Can't Have Heartbleed #Shorts🎥DeepDiveDev
SDL3 multiple custom fragment shaders [SDL3 Episode 30]🎥Mike Shah
Bazel Q3 2026 Community UpdateAnnouncements BazelCon 2026 With BazelCon fast approaching, we are excited to bring you a sneak peek of what’s to come, along with a few event announcements. Join the #bazelcon channel on Bazel Slack for real-time news and details. A Special Thanks to Our Sponsors To all our partners - both returning champions and brand-new supporters - thank you for consistently supporting our global community and making this event a reality. We are proud to have you on board! After-Hours Socializing & Networking No BazelCon is complete without post-session festivities! Unwind and connect with fellow engineers across a variety of social mixers, game nights, hackathons, and receptions. Tuesday, October 13th: (10 AM – 4 PM) BuildBarn Meetup hosted at DataDog (6 PM – 9 PM) Kickoff Event at the Postillion Convention Centre Wednesday, October 14th: (5:30 PM – 6:30 PM) BazelCon Attendee Reception at the Postillion Convention Centre (6 PM – 11 PM) Extreme Scale Party at Social Impact Factory (6:30 PM) BuildBuddy & Google Cloud Happy Hour at Ventuno Skylounge Friday, October 16th: (9 AM – 1 PM) Bazel Hackathon hosted at DataDog Remember to double check if you need to register via the link for the event of your choosing. BazelCon Training Day We are thrilled by the enthusiasm for the technical workshops led by our sponsors this year! A handful of seats remain across select tracks, so be sure to secure your preferred sessions on the schedule soon. If your schedule changes and you can no longer join us, please release your reservation to accommodate others on the waitlist. Important Note on Registration & Capacity Please keep in mind that venue space is limited. If you can no longer attend in person, kindly cancel your pass to make room for community members on the waitlist. Passes are also fully transferable to colleagues if you wish to reassign your spot. Simply locate your original confirmation email and select "Modify Registration" to manage your ticket. New bazel.build docsite This quarter the new bazel.build docsite has finally launched - a shared community success! Big thank you to all contributors for your time and effort put in making this idea a reality. We are continuously rolling out improvements and still rely on your help to catch remaining issues: - Report bugs: Check the Post-Migration tracker for known issues. If your bug isn't listed yet, please drop a comment here . - Contribute: Want to help improve the docs? You can find the guidelines at bazel.build/contribute/docs . - Discuss: Join the conversation in the #documentation Slack channel. Product Updates Upcoming Bazel releases Bazel 9.3.0 is expected to release on 2026-10-05. Q3 releases 9.2.0 was released in July ‘26. 8.8.0 was released in September ‘26, followed by patch 8.8.1 . Community Corner Updates from the JetBrains* team: Bazel for CLion plugin updates 2026.3 support is available on JetBrains Marketplace . New documentation for the plugin is published . You can now re-run individual tests directly from the IDE for our GoogleTest and Catch2 integrations. WeBazel.dev Bazel community member, Son Luong Ngoc, has launched a sleek new directory showcasing organizations using Bazel. The site offers intuitive filtering to explore verified adopters across the ecosystem. Each listing includes a specific confidence rating based on publicly available documentation, allowing you to inspect the underlying reference data directly. Love seeing cool community-led projects like this - huge thanks to Son for building such a valuable resource! Meetup.build events Four War Stories and a Demo: Seattle Build Meetup 2026 - in July, Uber and EngFlow co-hosted a Build meetup in Seattle. Missed it? Click the link and watch all five talk recordings. Keep an eye on meetup.build for next meetup announcements. Community created content Articles Bazel for iOS in 2026: What It Fixes and What It Breaks - by Mustafa Kemal Gökçe Say hello to the new bazel.build website - by Armando Montanez and Nikki Vijaybhaskar @EngFlow Autoconf’s revenge: ad-hoc shell templates - by Julio Merino Mojo is now open source! - by Modular Wallapop migrates to Bazel - by Mostfa Essam A matter of Facts, and why you should check in your MODULE.bazel.lock - by Jason Bedard A C++ toolchain from 357 bytes, in Bazel - by Farid Zakaria Videos Lightning Talk: Bazelizing a C++ Project - by Paulo Chiliguano Using Slang to answer 'what should we verify'? - by Clara Hollowood Titus Winters on Code Review, Builds, and Testing at 10x Commit Volume - by EngFlow Parallel merge queues for Bazel monorepos - by Mergify Resources GitHub repository: https://github.com/bazelbuild/bazel Releases: https://github.com/bazelbuild/bazel/releases Slack chat: https://slack.bazel.build Google group: bazel-discuss@googlegroups.com Special Interest Groups (SIG): Reach out the email(s) listed below if you’d like to be added to the SIG calendar invites. SIG Meeting frequency Point of contact Rules authors Every two weeks bazel-contrib@googlegroups.com Android app development Monthly ahumesky@google.com Bazel plugin for IntelliJ Monthly en@jetbrains.com Remote execution API working group Monthly chiwang@google.com Supply chain security / SBOM Weekly fwe@google.com Interested in learning about SIGs or starting a new one? Find more information on our website . Want to get your SIG listed? Please add it to the Community repository . Ideas, feedback, and submissions are welcome! Thank you for reading this edition! Let us know if you’d like to see any new information or changes in future community updates by reaching out to product@bazel.build. We look forward to hearing from you. Thanks, Google Bazel team * Copyright © 2026 JetBrains s.r.o. JetBrains and IntelliJ are registered trademarks of JetBrains s.r.o.📝Bazel Blog
Notes on coverageThis post is a collection of notes and (slightly cleaned up) summary of the research that went into my talk Mastering MC/DC from First Principles at Techtown this year. The history of code coverage The idea of code coverage is actually quite old. The oldest reference I found is the 1963 paper Systematic Mistake Analysis of Digital Computer Programs . Going through its references I also found another gem, A Control System For Logical Block Diagnosis With Data Loading , from 1960. This paper describes a system for writing tests for programs and running them, and it is fascinating just how sharp the observations were and how they are still true today. Here are a few quotes. Standard diagnostic systems require that the programmer read in sample data with his program and then follow the data through the program by means of memorydumps and breakpoint printing. Amusingly, printf debugging is older than printf. Printing whatever is in memory is an obvious and simple technique so it absolutely makes sense that it’s well established quite early in computers. It then goes on: For many programs this procedure is certainly satisfactory, but there are instances where additional aid from the diagnostic program is desirable. Which rings true today. Printf is quite useful, but it has some severe limitations. The approach which seems to be simplest and most efficient in this instance is to test the subroutine or logical block of instructions as a separate entity, that is, supply it with the selected test data, let the computer execute it, and then print out the results. To make the approach reasonable, it should be possible to execute all the necessary tests during one run. It’s describing a test runner/driver and framework (like catch2, boost.test, google test, pytest, etc) and this is how we test programs today. It is bizarre reading such a modern description when they elaborate specific test runs using punch cards: Print Card. This card is the control card for all breakpoint printing and memory or tape dumping. The RUN card is one of the principal new features of the system and gives the programmer much greater control of the diagnostic run […] Comes to show, really, that ideas truly last, while computer systems come and go. Automation of program debugging from 1961 is another paper that describes automated test suites. The idea of coverage doesn’t show up in that paper, but does so 1963 Systematic Mistake Analysis paper, which is a goldmine. They don’t actually use the term coverage, but they clearly explain the concept. From the introduction: The purpose of work reported here has been to develop a systematic way in which a programmer may test, all realistic combinations of input data, and hence all portions of a given program. Although at first this seems to be an arduous task, its handling is simplified by an orderly approach, and its reward is a greater assurance of the correctness and reliability of the program. The potential number of test cases is given by 2 B , where B is the number of branchpoints in the flowchart. What blew my mind is that this paper also describes the core property of prime path coverage; that loops must be entered, taken at least once, and skipped. My prime path coverage implementation landed in GCC 15 , 65 years later. One interesting thing with these papers, and a lot (most?) papers from the era, is that they discuss and describe programs in terms of flow charts or flow graphs and trees, and code does not really show up much. From the conclusion of Systematic Mistake Analysis: The tree is therefore an effective aid in the formulation of a test deck containing, for a given problem, all combinations of input that can be expected to occur . zcov is built on the idea that the graph is an excellent way of analyzing programs structure and coverage, and this paper demonstrates that neatly. The history of MC/DC The first paper I have found that references MC/DC is Applicability of modified condition/decision coverage to software testing from 1994. This paper thoroughly covers MC/DC, the motivation, and the strengths of the metric. Interestingly, it notes that MC/DC was not well known, but has been used for years in the avionics industry , and MC/DC was mandated by DO-178B in as early as 1992. I haven’t figured out exactly when MC/DC was developed, but presumably sometime in the late 80s. MC/DC has long been mandated for safety critical systems in spaceflight, automotive, trains, and presumably in other systems where faults could lead to death, harm, and massive damage. Its use outside of those industries are still somewhat limited. SQLite stands out as an example, but considering its use in aviation it falls under that regulation. The early 2000s saw two influential texts on MC/DC; A Practical Tutorial on Modified Condition/Decision Coverage and An Investigation of Three Forms of the Modified Condition Decision Coverage (MCDC) Criterion . These are good reads for understanding MC/DC and how to do it (by hand). I would not really recommend doing MC/DC by hand unless absolutely necessary as it is very error prone (and a bit dull), but their methods greatly influenced my GCC design. Unique-cause MC/DC has received most of the focus, which is an interesting historical artefact. In the 2001 report Rationale for Accepting Masking MC/DC in Certification Projects (CAST-6) 1 by the Certification Authorities Software Team they note that masking MC/DC should be acceptable. When DO-178B was written, the research on masking MC/DC was still being carried out; therefore, unique-cause MC/DC was the technique documented. Since that time, research has shown that masking MC/DC also meets the intent of the MC/DC objective. Therefore, it is proposed that masking MC/DC be considered an acceptable method for meeting MC/DC by applicants striving to meet the objectives of DO-178B, level A. Chilenski notes in his conclusion that masking MC/DC should be the preferred form. I personally support this conclusion and find masking MC/DC a more natural form which leverages Boolean algebra to great effect; it is more permissive when forming independence pairs and require fewer tests (but equivalent significant tests) while meeting the objective. Structural coverage Black box testing is designing test cases based on the specification (how the program/function is supposed to work) without regard for the program structure. White box testing is designing test cases based on the structure and uses the specification to predict the outcome of the test. Structural coverage is a measure of how our tests exercise the structures and components of the program. The word structure has echoes of Dijkstra’s famous essay Go To Statement Considered Harmful which argues in favours of structured blocks like while loops, if-then-else, etc. in favour of plain gotos. Another way of thinking about structure is the control flow graph (or diagram or chart, to use the 1960s terminology). By thinking of structure this way, and expanding individual conditions to blocks in the control flow graph, the structure becomes immediate and obvious as opposed to the familiar reading as source code. With this perspective it is clear that line (or even statement) coverage is very underwhelming. Here is an example from zcov, the SQLite function validJulianDay , which “unpacks” the expression return iJD into its actual structure. Chilenski and Miller provide an insight in the Applicability of MC/DC paper: An alternative approach that leverages the strength of both techniques is to develop functional tests from the specification and measure coverage against a structural criterion. In this way, the structural criterion is utilised as a test data adequacy criterion , rather than a test data selection criterion . This immediately became my favourite way of approaching about coverage. It has never been about meeting some arbitrary metric (except for regulation purposes, I suppose), but rather as an effective tool and finding discrepancies between the specification, the program, and the test suite. Any such discrepancy should be carefully investigated and understood. Both Hayhurst et al. and Chilenski 2001 discuss the testing technique at length, emphasising the importance of deriving test cases from intended behaviour and not incidental behaviour , we want tests to verify that the program does what it is supposed to, not lock in what it already does. Hayhurst et al. notes that including verification activities in every development step “builds in” quality, because “testing or analyzing in” quality at the end of the lifecycle is impractical. I would even argue impractical is a very soft way of putting it; no testing effort can fix a broken design, and earlier feedback (where coverage can be very valuable) can identify design problems before they settle. For all of this to work we need to always derive tests from the specification (black box) and not just mindlessly target code that happened to not be covered after the first batch of tests. Both testing and coverage tends to really pay off when coverage is already high; is an investment, and the value we draw from it is proportional to the effort we put in, and we find more problems (in both implementation an design) the more tests we write. What we want is not really the test itself, although it functions nicely to detect regressions, what we want is the process of writing tests. Coverage is a very objective measure and gives a signal on when to stop testing. If we find our tests adequate with respect to the requirements that also achieve (strong, e.g. MC/DC, not line) coverage we can stop testing and be confident that our program does what it is supposed to and nothing more. We can use it to avoid pointless tests; if a test does not meaningfully improve coverage it is likely that the behaviour it tests is already handled by some other test case, and I would argue a more minimal test suite is usually the better one. Coverage can be useful for challenging assumptions; if we design a test and expect that it should exercise some new structure (e.g. show the independence of a condition) and it does not something is wrong and we have a good seed for an analysis. What I think is a mistake is adding tests for the sake of improving coverage. It is mostly a pointless (but expensive!) effort as the real value to draw from coverage is the strong feedback into the relationship between the program, the specification, and the tests. However, using coverage to drive refactoring and redesign is an excellent use of the tool. Simplified MC/DC MC/DC is usually defined this way: Every statement in the program has been executed Every point of entry and exit has been invoked at least once Every control statement has taken all possible outcomes Every non-constant condition in a Boolean expression has taken on true and false Every non-constant condition in a Boolean expression as been shown to independently affect that expression’s outcome It is a bit of a mouthful, and I think we can generally simplify this to: Every condition has taken on true and false Every condition has been shown to independently affect the outcome The other properties are downstream of these two properties anyway (maybe except in the case of tautologies?), and we can focus on what makes MC/DC different. The independence criterion is the key property of MC/DC. Simply put, every condition should be able to decide the result of the Boolean expression. While it sounds obvious it is a bit subtle, but I like looking at it from the outside; if a condition cannot decide the outcome, why is it there, and is that really what we intended? What it means is that we disallow strongly coupled conditions which could force us to redesign. Such a rewrite usually means a simplification, which is undeniably a good thing. In An Investigation of Three Forms of MCDC Appendix B, Chilenski shows that MC/DC is a weak measure of equivalence class coverage. Since many bugs happen at value boundaries it makes sense to pay some extra attention here. References A Control System For Logical Block Diagnosis With Data Loading , M. Senko, Communications of the ACM, April 1960 Automation of program debugging , K. Jacoby and H. Layton, Proceedings of the 1961 16th ACM national meeting Systematic Mistake Analysis of Digital Computer Programs , J. C. Miller and C. J. Maloney, Communications of the ACM, February 1963 Applicability of modified condition/decision coverage to software testing , A Practical Tutorial on Modified Condition/Decision Coverage , K. J. Hayhurst et al., 2001 An Investigation of Three Forms of the Modified Condition Decision Coverage (MCDC) Criterion , J. Chilenski, 2001 Rationale for Accepting Masking MC/DC in Certification Projects (CAST-6), Certification Authorities Software Team, 2001 Go To Statement Considered Harmful , E. W. Dijkstra, Communications of the ACM, March 1968 A copy of this report plus some discussion is included in Hayhurst et al. , appendix B. ↩︎📝patch – BlogIf this page is useful, please consider donating a coffee
Thursday, October 1, 2026
Never Compare Floats With == #coding #programming #cppcoding #development #programminglanguages🎥PVS-Studio
Why factorial (10000) scrashes a tree-walking interpreter #coding #cpp #cppcoding #evaluator🎥PVS-Studio
Kitware Achieves CMMC Level 2 Assessment, Reinforcing Commitment to Secure Software DevelopmentKitware, a leader in software R&D and advanced AI, has achieved CMMC Level 2 (C3PAO) certification, reinforcing the company's commitment to protecting Controlled Unclassified Information (CUI) and supporting the cybersecurity requirements of the U.S. Department of War (DoW).📝Kitware Inc
Windows on Itanium also provided for hot-patching, in an even simpler wayOnce again, the benefit of fixed-length instructions. The post Windows on Itanium also provided for hot-patching, in an even simpler way appeared first on The Old New Thing .📝The Old New Thing
ParaView 6.2.0 Release NotesParaView 6.2.0 has been released! Notable additions to ParaView in this version highlighted in this post. For a comprehensive list of new features in ParaView 6.2.0, please see the ParaView 6.2.0 release notes hosted on ParaView’s GitLab project page. Performance optimizations for static meshes over time ParaView has been sped up significantly in some filters […]📝Kitware Inc
Junior vs Senior Developer: Adding Two Numbers (C++) #shorts🎥DeepDiveDev
Design Patterns - The Most Common Misconceptions (3 of N) - Klaus Iglberger - ACCU 2026🎥ACCUConf
Arno Lepisk: Linux shared libraries🎥SwedenCpp
Practical Testing: 46 - Timer Queue timers at shutdownOver the past few episodes of “Practical Testing” I’ve been implementing some changes to the real-world, multi-threaded code that I’ve been testing, using and developing for over 20 years. These changes have been to enable controlled shutdown. The changes have been designed, stubbed out, unit tests written and then the changes were implemented in one of the two timer systems, the timer wheel. In this, the final episode in this set of changes, we implement the changes in the timer queue.📝Rambling Comments - Len Holgate's blog
HTTP codes be like..🎥DeepDiveDev
A green master is a promise to your usersA green master is a promise to your users A stranger found your library. They have not read a line of your code yet. They glance at the CI badge and the date of the last commit, and in about thirty seconds they decide whether the project is alive and safe to depend on. A red badge, or a master branch last touched two years ago, and they leave. You won't hear from them about it.📝mp-unitsWednesday, September 30, 2026
Hello World in Assembly #coding #programming #assembly🎥DeepDiveDev
Make your C++ program faster with a single line of code🎥Code for yourself
C++ Serbia | Data Structures and Algorithms in Clinical Practice🎥cppserbia
Windows on AArch64 also provides for hot-patching, but it’s much simpler than on x86Fixed-length instructions makes it a much easier task. The post Windows on AArch64 also provides for hot-patching, but it’s much simpler than on x86 appeared first on The Old New Thing .📝The Old New Thing
Pulse v4.4.0 ReleaseThank you for being a valued member of the Pulse community! We’re pleased to share our latest release, an upcoming webinar, and a peek at what’s ahead. Pulse v4.4.0 is here! This release includes improvements to hemorrhage modeling, the option to enable a more detailed cardiopulmonary model that resolves individual bronchopulmonary segments, a new extracorporeal […]📝Kitware Inc
Qt 6.12 LTS Released!The 6.12 release for Qt Framework is now available, with improved cybersecurity, UI performance, and a wealth of capabilities to mix-and-match from across your architectural layers. As a Long-Term Support release , Qt 6.12 is not a simple incremental update, but a culmination of various efforts started years ago. Take a closer look.📝Qt Blog
C++ OPTIMIZATION Trick!! #c++ #programming #coding🎥DeepDiveDev
When (Not) to Patent Audio Software - Simon Hestermann - ADCx Copenhagen 2026🎥audiodevcon
Practical Testing: 45 - Timer Wheel timers at shutdownThis is the latest new episode of “Practical Testing” where I write about the most recent changes to some real-world, multithreaded code that I’ve been testing, using and developing for over 20 years. Now that we have sorted out the design for how we will manage the concept of shutting down the timer system we “just” have to implement it. We’ll start by doing the required work for the timer wheel implementation.📝Rambling Comments - Len Holgate's blog
SQL developers be like 🔊 #sql #programming #coding🎥DeepDiveDev
Recursive `make` and `-j`Today I looked into “recursive” invocations of make; that is, cases in which a Makefile recipe itself invokes make. The official documentation is quite good, but since I’m working with a range of different GNU Make versions, I looked at how the behavior has changed over time, from GNU Make 3.81 to 4.3.📝Arthur O’DwyerTuesday, September 29, 2026
Junior vs senior C++ developer 💻 #cpp #coding #programming #shorts🎥DeepDiveDev
Removing negative numbers from containers, a fun topic to talk about!🎥MeetingCpp
As a general rule, calling product support while drunk is not recommendedSwearing is also poor form. The post As a general rule, calling product support while drunk is not recommended appeared first on The Old New Thing .📝The Old New Thing
Introducing the Canvas2D Coding Skill for Agentic Development of Embedded Device UIsThe Challenge: Getting AI Agents to Draw Correct Canvas2D Qt 6.12 introduces Qt Canvas2D . Its API echoes the HTML5 canvas and the older Qt Quick Canvas element, both of which developers and AI models have seen many times in training data.📝Qt Blog
What Every C++ Programmer Needs to Know About AI - Jody Hagins - C++Now 2026🎥CppNow
Write your own ls (dir listing in C)🎥Jacob Sorber
Have you ever wondered how a compiler works?🎥PVS-Studio
Turn a video into ASCII art with C++ #shorts🎥DeepDiveDev
Practical Testing: 44 - Timers pending at shutdownThis is the latest new episode of “Practical Testing” where I write about the most recent changes to some real-world, multithreaded code that I’ve been testing, using and developing for over 20 years. As with most things that I’ve written on this blog over the years, the target audience is future me; if anyone else gets any value from anything then that’s a nice bonus. This set of changes, centre on how we handle shutting the timer system down.📝Rambling Comments - Len Holgate's blog
SDL3 custom fragment shaders with builtin API [SDL3 Episode 29]🎥Mike ShahMonday, September 28, 2026
Junior vs Senior C++ Developer 💀 #cpp #coding #programming #shorts🎥DeepDiveDev
Framatome Intercontrôle – Custom Developments to Optimize Non Destructive Testing Procedures Using a Robotic ArmAbout Framatome Intercontrôle Intercontrôle is a subsidiary of Framatome, specializing in automated Non Destructive Testing (NDT), in particular for safety-critical components of the primary circuits in nuclear reactors. It has been a leader in this field of activity for more than 50 years. They develop, qualify, and operate their inspection equipment on-site. The team therefore […]📝Kitware Inc
The Async Model is Here. Bring Your Own I/O (for now) — std::execution in C++26🎥Northwest C++ Users Group
C++20 Concepts – 101 - Amir Kirsh - C++Online 2026🎥CppOnline
C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple timesOnly on first execution. The post C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple times appeared first on The Old New Thing .📝The Old New Thing
C++ Weekly - Ep 552 - C++26's is_within_lifetime🎥Jason Turner
C++ virtual function has a hidden cost🎥DeepDiveDev
Designing Interactive Music Experiences in XR - Kasson Crooker - ADC Japan 2026🎥audiodevcon
Refactoring Towards Structured Concurrency - Roi Barkan - ACCU on Sea 2026🎥ACCUConf
Practical Testing: 43 - A performance tweakThis is the next in a series of blog posts, called “Practical Testing”, about testing real-world, multithreaded, code. Code that is in use for a long time goes through various evolutionary changes. The code that we feature in this series of articles is often the beating heart of server systems that are built with The Server Framework. Our many clients have varying performance requirements and changes for one client eventually feed back into the framework that is used by all of our clients.📝Rambling Comments - Len Holgate's blog
Let's make a programming language. Evaluator🎥PVS-Studio
Using C++17 std::optionalLet’s take a pair of two types - what can you do with such composition? In this article, I’ll describe std::optional - a helper “vocabulary” type added in C++17. It’s a wrapper that either contains a value of your type or is empty. Let’s see where it can be useful and how you can use it. Updated in September 2026 with C++20, C++23, and C++26 changes. Intro By adding the boolean flag to other types, you can achieve a thing called “nullable types”. As mentioned, the flag is used to indicate whether the value is available or not. Such wrapper represents an object that might be empty in an expressive way (so not via comments :)) While you can achieve “null-ability” by using unique values (-1, infinity, nullptr ), it’s not as clear as the separate wrapper type. Alternatively, you could even use std::unique_ptr and treat the empty pointer as not initialized - this works, but comes with the cost of allocating memory for the object. Optional types - that come from functional programming world - bring type safety and expressiveness. Most of other languages have something similar: for example std::option in Rust, Optional in Java, Data.Maybe in Haskell. std::optional was added in C++17 and brings a lot of experience from boost::optional that was available for many years. Since C++17 you can just #include and use the type. Such wrapper is still a value type (so you can copy it, via deep copy). What’s more, std::optional doesn’t need to allocate any memory on the free store. std::optional is a part of C++ vocabulary types along with std::any , std::variant and std::string_view . When to use Usually, you can use an optional wrapper in the following scenarios: If you want to represent a nullable type nicely. Rather than using unique values (like -1 , nullptr , NO_VALUE or something) For example, user’s middle name is optional. You could assume that an empty string would work here, but knowing if a user entered something or not might be important. With std::optional you get more information. Return a result of some computation (processing) that fails to produce a value and is not an error. For example finding an element in a dictionary: if there’s no element under a key it’s not an error, but we need to handle the situation. To perform lazy-loading of resources. For example, a resource type has no default constructor, and the construction is substantial. So you can define it as std::optional (and you can pass it around the system), and then load only if needed later. To pass optional parameters into functions. I like the description from boost optional which summarizes when we should use the type: From the boost::optional documentation: When to use Optional It is recommended to use optional in situations where there is exactly one, clear (to all parties) reason for having no value of type T , and where the lack of value is as natural as having any regular value of T While sometimes the decision to use optional might be blurry, you shouldn’t use it for error handling. As it best suits the cases when the value is empty and it’s a normal state of the program. Basic Example Here’s a simple example of what you can do with optional: std :: optional std :: string > UI :: FindUserNick () { if ( nick_available ) return { mStrNickName }; return std :: nullopt ; // same as return { }; } // use: std :: optional std :: string > UserNick = UI -> FindUserNick (); if ( UserNick ) Show ( * UserNick ); In the above code we define a function that returns optional containing a string. If the user’s nickname is available, then it will return a string. If not, then it returns nullopt . Later we can assign it to an optional and check (it converts to bool ) if it contains any value or not. Optional defines operator* so we can easily access the contained value. In the following sections you’ll see how to create std::optional , operate on it, pass around and even what is the performance cost you might want to consider. The C++17 Series This article is part of my series about C++17 Library Utilities. Here’s the list of the other topics that I’ll cover: Refactoring with std::optional Using std::optional (this post) Error handling and std::optional About std::variant About std::any In place construction for std::optional , std::variant and std::any std::string_view Performance C++17 string searchers & conversion utilities Working with std::filesystem Even more: Show me your code: std::optional A Wall of Your std::optional Examples Menu Class - Example of Modern C++17 STL features Resources about C++17 STL: C++17 In Detail by Bartek! C++17 - The Complete Guide by Nicolai Josuttis C++ Fundamentals Including C++ 17 by Kate Gregory Practical C++14 and C++17 Features - by Giovanni Dicanio C++17 STL Cookbook by Jacek Galowicz OK, so let’s move to std::optional . std::optional Creation There are several ways to create std::optional : // empty: std :: optional int > oEmpty ; std :: optional float > oFloat = std :: nullopt ; // direct: std :: optional int > oInt ( 10 ); std :: optional oIntDeduced ( 10 ); // deduction guides // make_optional auto oDouble = std :: make_optional ( 3.0 ); auto oComplex = make_optional std :: complex double >> ( 3.0 , 4.0 ); // in_place std :: optional std :: complex double >> o7 { std :: in_place , 3.0 , 4.0 }; // will call vector with direct init of {1, 2, 3} std :: optional std :: vector int >> oVec ( std :: in_place , { 1 , 2 , 3 }); // copy/assign: auto oIntCopy = oInt ; As you can see in the above code sample, you have a lot of flexibility with the creation of optional. It’s very simple for primitive types and this simplicity is extended for even complex types. The in_place construction is especially interesting, and the tag std::in_place is also supported in other types like any and variant . For example, you can write: // https://godbolt.org/g/FPBSak struct Point { Point ( int a , int b ) : x ( a ), y ( b ) { } int x ; int y ; }; std :: optional Point > opt { std :: in_place , 0 , 1 }; // vs std :: optional Point > opt {{ 0 , 1 }}; This saves the creation of a temporary Point object. I’ll address std::in_place later in a separate post, so stay tuned. Returning std::optional If you return an optional from a function, then it’s very convenient to return just std::nullopt or the computed value. std :: optional std :: string > TryParse ( Input input ) { if ( input . valid ()) return input . asString (); return std :: nullopt ; } In the above example you can see that I return std::string computed from input.asString() and it’s wrapped in optional . If the value is unavailable then you can just return std::nullopt . Of course, you can also declare an empty optional at the beginning of your function and reassign if you have the computed value. So we could rewrite the above example as: std :: optional std :: string > TryParse ( Input input ) { std :: optional std :: string > oOut ; // empty if ( input . valid ()) oOut = input . asString (); return oOut ; } It probably depends on the context which version is better. I prefer short functions, so I’d chose the first option (with multiple returns). Accessing The Stored Value Probably the most important operation for optional (apart from creation) is the way how you can fetch the contained value. There are several options: operator* and operator-> - similar to iterators. Accessing an empty optional is undefined behavior in C++17–23. C++26 adds checks in hardened implementations; see the update section below. value() - returns the value, or throws std::bad_optional_access value_or(defaultVal) - returns the value if available, or defaultVal otherwise. To check if the value is present you can use has_value() method or just check if (optional) as optional is automatically converted to bool . Here’s an example: // by operator* std :: optional int > oint = 10 ; std :: cout "oint " * opt1 '\n' ; // by value() std :: optional std :: string > ostr ( "hello" ); try { std :: cout "ostr " ostr . value () '\n' ; } catch ( const std :: bad_optional_access & e ) { std :: cout e . what () " \n " ; } // by value_or() std :: optional double > odouble ; // empty std :: cout "odouble " odouble . value_or ( 10.0 ) '\n' ; So the most useful way is probably just to check if the value is there and then access it: // compute string function: std :: optional std :: string > maybe_create_hello (); // ... if ( auto ostr = maybe_create_hello (); ostr ) std :: cout "ostr " * ostr '\n' ; else std :: cout "ostr is null \n " ; std::optional Operations Let’s see what are other operations on the type: Changing the value If you have existing optional object, then you can easily change the contained value by using several operations like emplace , reset , swap , assign. If you assign (or reset) with a nullopt then if the optional contains a value its destructor will be called. Here’s a little summary: #include #include #include class UserName { public : explicit UserName ( const std :: string & str ) : mName ( str ) { std :: cout "UserName::UserName( \' " ; std :: cout mName " \' ) \n " ; } ~ UserName () { std :: cout "UserName::~UserName( \' " ; std :: cout mName " \' ) \n " ; } private : std :: string mName ; }; int main () { std :: optional UserName > oEmpty ; // emplace: oEmpty . emplace ( "Steve" ); // calls ~Steve and creates new Mark: oEmpty . emplace ( "Mark" ); // reset so it's empty again oEmpty . reset (); // calls ~Mark // same as: //oEmpty = std::nullopt; // assign a new value: oEmpty . emplace ( "Fred" ); oEmpty = UserName ( "Joe" ); } The code is available here: @Coliru Comparisons std::optional allows you to compare contained objects almost “normally”, but with a few exceptions when the operands are nullopt . See below: #include #include int main () { std :: optional int > oEmpty ; std :: optional int > oTwo ( 2 ); std :: optional int > oTen ( 10 ); std :: cout std :: boolalpha ; std :: cout ( oTen > oTwo ) " \n " ; std :: cout ( oTen oTwo ) " \n " ; std :: cout ( oEmpty oTwo ) " \n " ; std :: cout ( oEmpty == std :: nullopt ) " \n " ; std :: cout ( oTen == 10 ) " \n " ; } The above code generates: true // (oTen > oTwo) false // (oTen The code is available here: @Coliru Examples of std::optional Here are two a few longer examples where std::optional fits nicely. User name with an optional nickname and age #include #include class UserRecord { public : UserRecord ( const std :: string & name , std :: optional std :: string > nick , std :: optional int > age ) : mName { name }, mNick { nick }, mAge { age } { } friend std :: ostream & operator ( std :: ostream & stream , const UserRecord & user ); private : std :: string mName ; std :: optional std :: string > mNick ; std :: optional int > mAge ; }; std :: ostream & operator ( std :: ostream & os , const UserRecord & user ) { os user . mName ' ' ; if ( user . mNick ) { os * user . mNick ' ' ; } if ( user . mAge ) os "age of " * user . mAge ; return os ; } int main () { UserRecord tim { "Tim" , "SuperTim" , 16 }; UserRecord nano { "Nathan" , std :: nullopt , std :: nullopt }; std :: cout tim " \n " ; std :: cout nano " \n " ; } The code is available here: @Coliru Parsing ints from the command line #include #include #include std :: optional int > ParseInt ( char * arg ) { try { return { std :: stoi ( std :: string ( arg )) }; // or from_chars... } catch (...) { std :: cout "cannot convert \' " arg " \' to int! \n " ; } return { }; } int main ( int argc , char * argv []) { if ( argc >= 3 ) { auto oFirst = ParseInt ( argv [ 1 ]); auto oSecond = ParseInt ( argv [ 2 ]); if ( oFirst && oSecond ) { std :: cout "sum of " * oFirst " and " * oSecond ; std :: cout " is " * oFirst + * oSecond " \n " ; } } } The code is available here: @Coliru The above code uses optional to indicate if we performed the conversion or not. Note that we in fact converted exceptions handling into optional, so we skip the errors that might appear. This might be “controversial” as usually, we should report errors. C++17 also offers std::from_chars , which parses numbers without throwing exceptions or allocating memory. See my article C++ String Conversion: Exploring std::from_chars in C++17 to C++26 for examples, including a parser that returns std::optional . Other examples Representing other optional entries for your types. Like in the example of a user record. It’s better to write std::optonal rather than use a comment to make notes like // if the 'key is 0x7788 then it's empty or something :) Return values for Find*() functions (assuming you don’t care about errors, like connection drops, database errors or something) See more in: A Wall of Your std::optional Examples - C++ Stories Performance & Memory consideration When you use std::optional you’ll pay with increased memory footprint. At least one extra byte is needed. Conceptually your version of the standard library might implement optional as: template typename T > class optional { bool _initialized ; std :: aligned_storage_t sizeof ( T ), alignof ( T ) > _storage ; public : // operations }; In short optional just wraps your type, prepares a space for it and then adds one boolean parameter. This means it will extend the size of your Type according do the alignment rules. There was one comment about this construction : “And no standard library can implement optional this way (they need to use a union, because constexpr)”. So the code above is only to show an example, not real implementation. Alignment rules are important as The standard defines: Class template optional [optional.optional]: The contained value shall be allocated in a region of the optional storage suitably aligned for the type T. For example: // sizeof(double) = 8 // sizeof(int) = 4 std :: optional double > od ; // sizeof = 16 bytes std :: optional int > oi ; // sizeof = 8 bytes While bool type usually takes only one byte, the optional type need to obey the alignment rules and thus the whole wrapper is larger than just sizeof(YourType) + 1 byte . For example, if you have a type like: struct Range { std :: optional double > mMin ; std :: optional double > mMax ; }; it will take more space than when you use your custom type: struct Range { bool mMinAvailable ; bool mMaxAvailable ; double mMin ; double mMax ; }; In the first case, we’re using 32 bytes! The second version is 24 bytes. Test code using Compiler Explorer Here’s a great description about the performance and memory layout taken from boost documentation: Performance considerations - 1.67.0 . And in Efficient optional values | Andrzej’s C++ blog the author discusses how to write a custom optional wrapper that might be a bit faster I wonder if there’s a chance to do some compiler magic and reuse some space and fit this extra “initialized flag” inside the wrapped type. So no extra space would be needed. Migration from boost::optional std::optional was adapted directly from boost::optional , so you should see the same experience in both versions. Moving from one to another should be easy, but of course, there are little differences. In the paper: N3793 - A proposal to add a utility class to represent optional objects (Revision 4) - from 2013-10-03 I’ve found the following table (and I tried to correct it when possible with the current state). aspect std::optional boost::optional (as of 1.67.0 ) Move semantics yes no yes in current boost noexcept yes no yes in current boost hash support yes no a throwing value accessor yes yes literal type (can be used in constexpr expressions) yes no in place construction `emplace`, tag `in_place` emplace() , tags in_place_init_if_t , in_place_init_t , utility in_place_factory disengaged state tag nullopt none optional references C++17–23: no; C++26: yes ( optional ) yes conversion from optional to optional yes yes explicit convert to ptr ( get_ptr ) no yes deduction guides yes no Special case: optional and optional While you can use optional on any type you need to pay special attention when trying to wrap boolean or pointers. std::optional ob - what does it model? With such construction you basically have a tri-state bool. So if you really need it, then maybe it’s better to look for a real tri-state bool like boost::tribool . Whet’s more it might be confusing to use such type because ob converts to bool if there’s a value inside and *ob returns that stored value (if available). Similarly you have a similar confusion with pointers: // don't use like that! only an example! std :: optional int *> opi { new int ( 10 ) }; if ( opi && * opi ) { std :: cout ** opi std :: endl ; delete * opi ; } if ( opi ) std :: cout "opi is still not empty!" ; The pointer to int is naturally “nullable”, so wrapping it into optional makes it very hard to use. Changes in C++20, C++23, and C++26 C++17 was published a long time ago, let’s find out how std::optional evolved over the recent years: C++20: Comparisons and constexpr C++20 adds operator (spaceship) for optionals. For example: #include #include constexpr std :: optional int > empty ; constexpr std :: optional int > two = 2 ; constexpr std :: optional int > ten = 10 ; static_assert (( two ten ) 0 ); // compares the stored values static_assert (( empty two ) 0 ); // empty comes before a value static_assert (( empty empty ) == 0 ); The stored types must support the required comparisons. See the C++20 specification . C++17 already allowed constructing an optional from a value at compile time. P2231R1 added missing constexpr support for operations like emplace() , reset() , assignment, swapping, and converting constructors. It was adopted during C++23 work as a defect report against C++20 . For example, with that change we can write: #include constexpr int compute () { std :: optional int > value ; value . emplace ( 42 ); value . reset (); return value . value_or ( 7 ); } static_assert ( compute () == 7 ); See @Compiler Explorer The operations on the stored type must also work at compile time. C++23: Monadic operations C++23 adds three functions for chaining operations on optionals ( P0798R8 ): transform() applies a function to the stored value and wraps the result in an optional. and_then() calls a function that already returns an optional, without adding another optional around it. or_else() calls a fallback function when the optional is empty. The function returns an optional of the same type. transform() and and_then() skip the function call when the optional is empty. These functions do not catch exceptions. I covered them with examples in a separate article: How to Use Monadic Operations for std::optional in C++23 . C++23 also adds std::expected . Consider it when the caller needs to know why an operation failed, rather than just whether a value is available. C++26: Range support C++26 adds begin() and end() and makes optional a ranges view ( P3168R2 ). A loop over an optional runs once if there’s a value, or not at all if it’s empty: std :: optional int > value = 42 ; for ( int x : value ) std :: cout x '\n' ; // prints 42 once This also lets us use std::views::join on a range of optionals to visit the values and skip empty entries. C++26: Optional references C++26 adds std::optional ( P2988R12 ). It can refer to an existing object or be empty: int first = 10 ; int second = 20 ; std :: optional int &> ref { first }; * ref = 15 ; // changes first ref . emplace ( second ); // now refers to second * ref = 25 ; // changes second Notice that emplace() changes which object we refer to, while writing through *ref changes the object itself. The optional does not own the object or keep it alive. C++26: Hardened access With a hardened standard library, operator* and operator-> check that the optional has a value before accessing it ( P3471R4 ). Without hardening, accessing an empty optional this way still has undefined behavior. Use value() if you want an exception when the optional is empty. See here: #include #include #include int main () { std :: optional std :: string > nick = "SuperTim" ; std :: print ( "{} \n " , * nick ); // OK: contains a value std :: print ( "{} \n " , nick -> size ()); // OK: contains a value nick . reset (); // now empty try { std :: print ( "{} \n " , nick . value ()); } catch ( const std :: bad_optional_access & ) { std :: print ( "No nickname \n " ); } // fails the hardening check, comment this line //std::print("{}\n", *nick); } See @Compiler Explorer With the line uncommented, I’m getting: rogram stderr optional.h:524: libc++ Hardening assertion this->has_value() failed: optional operator* called on a disengaged value Program terminated with signal SIGABRT (6) For more see my C++26: Standard Library Hardening Experiments . Support for these C++26 features depends on your compiler and standard library. Wrap up Uff… ! it was a lot of text about optional, but still it’s not all :) Yet, we’ve covered the basic usage, creation and operations of this useful wrapper type. I believe we have a lot of cases where optional fits perfectly and much better than using some predefined values to represent nullable types. I’d like to remember the following things about std::optional : std::optional is a wrapper type to express “null-able” types. std::optional won’t use any dynamic allocation std::optional contains a value or it’s empty use operator * , operator-> , value() or value_or() to access the underlying value. std::optional is implicitly converted to bool so that you can easily check if it contains a value or not. In the next article I’ll try to explain error handling and why optional is maybe not the best choice there. I’d like to thank Patrice Roy ( @PatriceRoy1 ), Jacek Galowicz ( @jgalowicz ) and Andrzej Krzemienski ( akrzemi ) for finding time do do a quick review of this article!📝C++ StoriesSunday, September 27, 2026
What are we synchronizing?🎥GlobalCpp
This C++ code runs in 0 seconds🎥DeepDiveDev
Can C++ Become a Memory Safe Language? - Prabhu Missier - C++Now 2026🎥CppNow
Using AI to Finish Multiplayer Servers for Hazel🎥The Cherno
2025 Keynote Speaker SEAN PARENT - Are We There Yet?🎥cppunderthesea
Using Renderdoc with SDL3 to reverse engineer the graphics pipeline [SDL3 Episode 28]🎥Mike Shah

