Planet Me

August 28, 2026

ISO C++

When The C/C++ Users Journal Disappeared -- Chuck Allison

stacks-image-75c5e1f.jpgThis article chronicles the rise and fall the C/C++ Users Journal, and the creation of The C++ Source, which filled the interim until isocpp.org came online.

When The C/C++ Users Journal Disappeared

by Chuck Allison

From the article:

Today, if you have a question, you search the web or have ask an AI chatbot. In the early 1980s there was the C Programming Language, but:

  • there was no web
  • there was no Stack Overflow,
  • there was no GitHub,
  • there was often no Internet access at all.

The C++ programming language had a creator, an organically emerging user community followed by a standards committee, and a vibrant ecosystem of writers and contributors.

The ecosystem part is often forgotten.

by ChuckAllison at August 28, 2026 11:27 PM

CppCon 2026 When Zero-Cost Abstractions Aren't Zero-Cost -- Steve Sorkin

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

When Zero-Cost Abstractions Aren't Zero-Cost

Thursday, September 17, 2026 14:00 - 15:00 MDT

by Steve Sorkin

Summary of the talk:

Zero-cost abstractions are a foundational idea in C++, promising expressive, high-level code without sacrificing performance. However, developers often encounter unexpected costs when using modern abstractions in practice, even when the code appears idiomatic and well-designed.

This talk explores the assumptions behind zero-cost abstractions and examines what happens when those assumptions no longer hold. Through concrete examples drawn from modern C++ — including ranges and views, type erasure, allocators, and other common abstractions — we will examine how factors such as optimizer visibility, inlining boundaries, allocation behavior, and runtime flexibility influence performance.

This talk treats abstraction as a powerful engineering tool, examining the limits of its zero-cost guarantees in real-world systems. We will look at how seemingly small design choices can introduce hidden costs, why those costs are often difficult to spot through inspection alone, and how to recover performance without abandoning good design or readability.

Attendees will leave with a clearer understanding of when abstractions are truly zero-cost, how to recognize situations where they are not, and how to make informed tradeoffs between expressiveness, flexibility, and performance in modern C++.

by Blog Staff at August 28, 2026 07:14 PM

Parallel Directory Traversal -- Daniel Gómez Vergel

Parallelizing a directory traversal is an excellent exercise for exploring concurrency in C++. This article presents a complete implementation built with standard C++ facilities.

Parallel Directory Traversal

by Daniel Gómez Vergel

From the article:

Given the path of a directory, our goal is to produce a statistical summary of the contents of its directory tree. For each file extension encountered (.txt, .zip, and so on), we will determine both the number of files and their cumulative size. The analysis will also report the total number of subdirectories discovered during the traversal.

In this implementation, we will parallelize the directory tree traversal itself. Each worker thread will process directories retrieved from a shared concurrent queue, discover any subdirectories they contain, and dynamically push them into the queue so that they can later be processed by any available worker. As a result, multiple threads will be able to explore different branches of the directory tree simultaneously while accumulating partial statistics that will ultimately be merged into a single global result.

by Daniel G Vergel at August 28, 2026 04:25 PM

PVS-Studio 8.00

PVS-Studio 8.00 has been released. This version features new analyzers for JavaScript, TypeScript and Go projects, new IDE plugins for WebStorm and GoLand, expanded support for MISRA C++ 2023, and much more.

PVS-Studio 8.00

by Valerii Filatov

From the article:

In the release, we have also expanded the list of C and C++ compilers that are compatible with the PVS-Studio analyzer for these languages. On Linux, the pvs-studio-analyzer utility supports the x86_64-pc-linux-gnu-c++ compiler. The TI C2000-CGT compiler is also supported on all platforms via compilation monitoring and tracing.

 

by Andrey Karpov at August 28, 2026 10:24 AM

BeCPP Symposium 2026 - Andre Kostur - There’s a Hole in the C++ Type System

BeCPP Symposium 2026 (organized by BeCPP): Now on YouTube!

Andre Kostur - There’s a Hole in the C++ Type System

Abstract:

This is a story of identifying what I think is a hole in the C++ type system, describing a mitigation strategy, and starting the process of engaging the Committee with a change to the C++ language that would help users write the affected classes in a simpler and more intuitive way. With luck, this change may make it into C++29.

About the Speaker:

Andre Kostur has over 30 years of experience as a professional C++ developer, with a focus on designing and developing network solutions. As a young graduate he was responsible for introducing C++ to his employer; convincing them to take a chance on a language that was still years away from initial standardization.
As a corporate champion of C++ as well as the founder and lead of multiple C++ user groups, Andre routinely presents on all things C++ from the basics to the latest developments. His speaking credits also include corporate presentations and appearing as a speaker at CPPCon.
Andre is a member of the Standards Council of Canada one of the Canadian representatives on the ISO C++ Committee; and an active member of the online C++ community.

 

by Marc Gregoire at August 28, 2026 06:28 AM

XKCD

August 27, 2026

ISO C++

Automated Unit Testing On-The-Cheap: Part 2 -- Chuck Allison

Chuck Allison concludes his two-part series revisiting a minimalist unit-testing framework originally developed for teaching C++. Part 2 modernizes the design using facilities such as std::source_location and inline variables while preserving the framework’s emphasis on simplicity and minimal overhead. The article also reflects on how the evolution of the C++ language has simplified framework implementation over the past 25 years.

Automated Unit Testing On-The-Cheap: Part 2

by Chuck Allison

From the article:

In Part 1 of this two-part series I introduced a time-tested (i.e., old grin) technique that handled automated unit testing in a remarkably simple way, including validating proper exception handling. The previous post left two problems on the table, however, and the journey to fix them turns out to be a nice tour of two key features of modern C++: inline variables and modules.

The simplicity of the test framework discussed in Part 1 follows from everything being contained in a small header file, test.h (include guards not shown):

by ChuckAllison at August 27, 2026 11:23 PM

The Daily WTF

CodeSOD: The Big Family

Some time ago, Charles shared with us some awful PHP, aka the most common sort. Today's code sample is maybe a little too big to sum up, but I'll let Charles take a crack at it.

It's so bad that even analyzing and laughing at it feels impossible. But it’s so bad, I couldn’t not share it.

I’m the only one handling all the IT-related tasks at my company, and I don’t have anyone here to vent or laugh about this kind of thing with. So, I figured, why not share it here? I’m hoping it’ll provide at least a little bit of catharsis or some dark humor.

To make sure the confidentiality of the codebase was respected, I took the liberty of generalizing it. You might notice some inconsistencies, but that’s just me trying to keep things neutral while protecting the original structure and functionality. Apologies if it looks a bit patchy – the goal was to avoid revealing any specific details or sensitive code.

The whole block is north of 400 lines, and it's doing a lot. Or well, maybe it's not, as you'll see.

Let's star with the outermost layer.

$resm_data = $data_source->fetchData("group=" . $item_id);
foreach ($resm_data as $key => $value) {
// rest of the code here
}

We fetch data from a data source, presumably a database, passing our condition as a string, which reeks of probable SQL injection, but I don't know what library they're using. I also note they're using the key/value style of array iteration, but never actually check the key.

    $option_id = $value->option_id;
    $resm_details = $detail_source->fetch($option_id);
    if ($resm_details) {
        $label = $resm_details->{"label$lang"};
        $description = $resm_details->{"description$lang"};
        $category = $resm_details->category;

Nice little bit of "meta" programming to get their localization working, it'll fetch labelen or labelde as needed. Definitely not a horrible, dangerous way to solve that problem.

We use that again to get our currency figured out. That lets us do number formatting. So much number formatting code.

        if ($category == 0) {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = $resm_details->{"child_cost" . $currency};
            $cost_info =
                $mot[101] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol . " - " .
                $mot[102] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
        } elseif ($category == 1) {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = 0;
            $cost_info = $mot[101] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol;
        } elseif ($category == 2) {
            $cost = 0;
            $child_cost = $resm_details->{"child_cost" . $currency};
            $cost_info = $mot[102] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
        } elseif ($category == 4) {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = 0;
            $cost_info = $mot[500] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol;
        } elseif (
            $resm_details->{"cost" . $currency} == 0 and
            $resm_details->{"child_cost" . $currency} == 0
        ) {
            $cost = 0;
            $child_cost = 0;
            $cost_info = "";
        } else {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = 0;
            $cost_info = $mot[200] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol;
        }

What is the $mot array? Why am I jumping to seemingly random locations in that array? Clearly it contains some headers for our output.

Anyway, there's plenty of HTML string munging happening too, don't you worry.

        if ($location == 1) {
            $quantity_block =
                '<div class="quantity-container">
                    <input type="text" value="1" id="quantity-' . $option_id . '" class="qty-control" name="quantity" min="1" max="1">
                    <div class="increase button">+</div>
                    <div class="decrease button">-</div>
                </div>';
            $quantity = 1;
        } else {
            $quantity_block = "";
            $quantity = "all";
        }

And then there's this little treat for parsing the time stored in our database: $time_data = json_decode($resm_details->time_data); That tells me they're storing date times as strings, so that's fun.

There are also a couple more bon mots as they build a drop down list:

            $departure_select = '<option value="-1">' . $mot[300] . '</option>';
            $arrival_select = '<option value="-1">' . $mot[301] . '</option>';

And then there's this monstrosity:

        // Add the main option to the template
        $TEMPLATE->SET_BLOCK_VARIABLES("Block_OPTIONS", [
            "ID" => $option_id,
            "QUANTITY" => $quantity,
            "LABEL_CLASS" => $label_class,
            "ACTION_CLASS" => $action_class,
            "LABEL" => $label,
            "DESCRIPTION" => $description,
            "QUANTITY_BLOCK" => $quantity_block,
            "COST_INFO" => $cost_info,
            "HOST_COST_DISPLAY" => $host_cost_display,
            "COST" => $cost,
            "CHILD_COST" => $child_cost,
            "LOCATION" => $location,
            "CATEGORY" => $category,
            "HOST_CLASS" => $host_class,
            "EXTRA" => $extra,
            "HOST_EXTRA" => $host_extra,
            "TIME_CHECKED" => ($has_times == 1) ? 'selected="' . $option_id . '" checked="true"' : '',
            "TIME_BLOCK" => $time_block
        ]);

All the nonsense that we concatenate together above gets shoved into some sort of template. And after that, that's where the good stuff starts. Because guess what? We have to do the same thing for child items.

        $resm_children_data = $data_source->fetchData("parent=" . $option_id);
        foreach ($resm_children_data as $child_key => $child_value) {
            $child_option_id = $child_value->option_id;
            $resm_child_details = $detail_source->fetch($child_option_id);

That's right, it's the same block of code, not quite copy/pasted, since they needed to put the word child in everything.

                // Add the child option to the template
                $TEMPLATE->SET_BLOCK_VARIABLES("Block_OPTIONS.Block_OPTIONS_CHILD", [
                    "ID" => $child_option_id,
                    "QUANTITY" => $child_quantity,
                    "LABEL_CLASS" => $child_label_class,
                    "ACTION_CLASS" => $child_action_class,
                    "LABEL" => $child_label,
                    "DESCRIPTION" => $child_description,
                    "QUANTITY_BLOCK" => $child_quantity_block,
                    "COST_INFO" => $child_cost_info,
                    "HOST_COST_DISPLAY" => $child_host_cost_display,
                    "COST" => $child_cost,
                    "CHILD_COST" => $child_extra_cost,
                    "LOCATION" => $child_location,
                    "CATEGORY" => $child_category,
                    "HOST_CLASS" => $child_host_class,
                    "EXTRA" => $child_extra,
                    "HOST_EXTRA" => $child_host_extra,
                    "TIME_CHECKED" => ($child_has_times == 1) ? 'selected="' . $child_option_id . '" checked="true"' : '',
                    "TIME_BLOCK" => $child_time_block
                ]);

And now, if you liked the child record, guess what? Those children have got siblings. What can I say, it's a big family.

                $resm_sibling_data = $data_source->fetchData("parent=" . $parent_option_id);
                foreach ($resm_sibling_data as $sibling_key => $sibling_value) {
                    $sibling_option_id = $sibling_value->option_id;
                    $resm_sibling_details = $detail_source->fetch($sibling_option_id);

And that means, yes, we also use that template thing again:

                        // Add the sibling option to the template
                        $TEMPLATE->SET_BLOCK_VARIABLES("Block_OPTIONS.Block_OPTIONS_CHILD", [
                            "ID" => $sibling_option_id,
                            "QUANTITY" => $sibling_quantity,
                            "LABEL_CLASS" => $sibling_label_class,
                            "ACTION_CLASS" => $sibling_action_class,
                            "LABEL" => $sibling_label,
                            "DESCRIPTION" => $sibling_description,
                            "QUANTITY_BLOCK" => $sibling_quantity_block,
                            "COST_INFO" => $sibling_cost_info,
                            "HOST_COST_DISPLAY" => $sibling_host_cost_display,
                            "COST" => $sibling_cost,
                            "SIBLING_COST" => $sibling_extra_cost,
                            "LOCATION" => $sibling_location,
                            "CATEGORY" => $sibling_category,
                            "HOST_CLASS" => $sibling_host_class,
                            "EXTRA" => $sibling_extra,
                            "HOST_EXTRA" => $sibling_host_extra,
                            "TIME_CHECKED" => ($sibling_has_times == 1) ? 'selected="' . $sibling_option_id . '" checked="true"' : '',
                            "TIME_BLOCK" => $sibling_time_block
                        ]);

Someday, I hope the person who wrote this learn about methods and function calls. Maybe they could write their own one day.

In any case, here's the whole thing:

$resm_data = $data_source->fetchData("group=" . $item_id);
foreach ($resm_data as $key => $value) {
    $option_id = $value->option_id;
    $resm_details = $detail_source->fetch($option_id);
    if ($resm_details) {
        $label = $resm_details->{"label$lang"};
        $description = $resm_details->{"description$lang"};
        $category = $resm_details->category;

        // Process cost based on category
        if ($category == 0) {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = $resm_details->{"child_cost" . $currency};
            $cost_info =
                $mot[101] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol . " - " .
                $mot[102] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
        } elseif ($category == 1) {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = 0;
            $cost_info = $mot[101] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol;
        } elseif ($category == 2) {
            $cost = 0;
            $child_cost = $resm_details->{"child_cost" . $currency};
            $cost_info = $mot[102] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
        } elseif ($category == 4) {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = 0;
            $cost_info = $mot[500] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol;
        } elseif (
            $resm_details->{"cost" . $currency} == 0 and
            $resm_details->{"child_cost" . $currency} == 0
        ) {
            $cost = 0;
            $child_cost = 0;
            $cost_info = "";
        } else {
            $cost = $resm_details->{"cost" . $currency};
            $child_cost = 0;
            $cost_info = $mot[200] . " : +" . number_format($cost, 2, ",", " ") . $currency_symbol;
        }

        $location = $resm_details->location;
        $label_class = $location == 1 ? "has-quantity" : "no-quantity";
        $action_class = $location == 1 ? "active-with-quantity" : "active-no-quantity";
        if ($location == 1) {
            $quantity_block =
                '<div class="quantity-container">
                    <input type="text" value="1" id="quantity-' . $option_id . '" class="qty-control" name="quantity" min="1" max="1">
                    <div class="increase button">+</div>
                    <div class="decrease button">-</div>
                </div>';
            $quantity = 1;
        } else {
            $quantity_block = "";
            $quantity = "all";
        }

        $has_times = $resm_details->has_times;

        if ($has_times == 1) {
            $time_counter++;
            $time_data = json_decode($resm_details->time_data);

            $departure_select = '<option value="-1">' . $mot[300] . '</option>';
            $arrival_select = '<option value="-1">' . $mot[301] . '</option>';

            $departures = $time_data->departures;
            $arrivals = $time_data->arrivals;

            foreach ($departures as $dep_key => $departure) {
                $departure_select .= '<option value="' . $dep_key . '">' . $departure . '</option>';
            }

            foreach ($arrivals as $arr_key => $arrival) {
                $arrival_select .= '<option value="' . $arr_key . '">' . $arrival . '</option>';
            }

            $departure_block = '<div class="col-half time-select-' . $option_id . '" style="padding-right: 0;">
                <select class="form-control time-departure" style="text-align: center;">' . $departure_select . '</select>
                </div>';

            $arrival_block = '<div class="col-half time-select-' . $option_id . '" style="padding-left: 0;">
                <select class="form-control time-arrival" style="text-align: center;">' . $arrival_select . '</select>
                </div>';

            $time_block = '<div class="row time-container">
                ' . $departure_block . $arrival_block . '
            </div><small class="error-message time-error">' . $mot[302] . '</small>';
        } else {
            $time_block = '';
        }

        $host_cost_display = "";
        $extra = $resm_details->extra;
        $host_extra = $resm_details->host_extra;
        $host_class = "";

        if ($extra == 1) {
            $extra_cost_1 = $resm_details->{"cost" . $currency . "_1"};
            $extra_cost_2 = $resm_details->{"cost" . $currency . "_2"};

            $default_extra = $host_price == 0 ? $extra_cost_2 : $extra_cost_1;
            $cost_info = $mot[101] . ' : +<span class="extra-cost">' . number_format($default_extra, 2, ",", " ") .
                "</span>" . $currency_symbol . " - " . $mot[102] . ' : +<span class="child-cost">0.00</span>' . $currency_symbol;

            $host_class = " extra-option";
        }
        if ($host_extra == 1) {
            $host_cost_display =
                '<span class="host-cost">' . $mot[500] . ' : +<span class="host-price">0.00</span>' . $currency_symbol .
                "</span><br>";
        }

        // Add the main option to the template
        $TEMPLATE->SET_BLOCK_VARIABLES("Block_OPTIONS", [
            "ID" => $option_id,
            "QUANTITY" => $quantity,
            "LABEL_CLASS" => $label_class,
            "ACTION_CLASS" => $action_class,
            "LABEL" => $label,
            "DESCRIPTION" => $description,
            "QUANTITY_BLOCK" => $quantity_block,
            "COST_INFO" => $cost_info,
            "HOST_COST_DISPLAY" => $host_cost_display,
            "COST" => $cost,
            "CHILD_COST" => $child_cost,
            "LOCATION" => $location,
            "CATEGORY" => $category,
            "HOST_CLASS" => $host_class,
            "EXTRA" => $extra,
            "HOST_EXTRA" => $host_extra,
            "TIME_CHECKED" => ($has_times == 1) ? 'selected="' . $option_id . '" checked="true"' : '',
            "TIME_BLOCK" => $time_block
        ]);

        $resm_children_data = $data_source->fetchData("parent=" . $option_id);
        foreach ($resm_children_data as $child_key => $child_value) {
            $child_option_id = $child_value->option_id;
            $resm_child_details = $detail_source->fetch($child_option_id);
            if ($resm_child_details) {
                $child_label = $resm_child_details->{"label$lang"};
                $child_description = $resm_child_details->{"description$lang"};
                $child_category = $resm_child_details->category;

                // Process cost for child category
                if ($child_category == 0) {
                    $child_cost = $resm_child_details->{"cost" . $currency};
                    $child_extra_cost = $resm_child_details->{"child_cost" . $currency};
                    $child_cost_info =
                        $mot[101] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol . " - " .
                        $mot[102] . " : +" . number_format($child_extra_cost, 2, ",", " ") . $currency_symbol;
                } elseif ($child_category == 1) {
                    $child_cost = $resm_child_details->{"cost" . $currency};
                    $child_extra_cost = 0;
                    $child_cost_info = $mot[101] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
                } elseif ($child_category == 2) {
                    $child_cost = 0;
                    $child_extra_cost = $resm_child_details->{"child_cost" . $currency};
                    $child_cost_info = $mot[102] . " : +" . number_format($child_extra_cost, 2, ",", " ") . $currency_symbol;
                } elseif ($child_category == 4) {
                    $child_cost = $resm_child_details->{"cost" . $currency};
                    $child_extra_cost = 0;
                    $child_cost_info = $mot[500] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
                } elseif (
                    $resm_child_details->{"cost" . $currency} == 0 and
                    $resm_child_details->{"child_cost" . $currency} == 0
                ) {
                    $child_cost = 0;
                    $child_extra_cost = 0;
                    $child_cost_info = "";
                } else {
                    $child_cost = $resm_child_details->{"cost" . $currency};
                    $child_extra_cost = 0;
                    $child_cost_info = $mot[200] . " : +" . number_format($child_cost, 2, ",", " ") . $currency_symbol;
                }

                $child_location = $resm_child_details->location;
                $child_label_class = $child_location == 1 ? "has-quantity" : "no-quantity";
                $child_action_class = $child_location == 1 ? "active-with-quantity" : "active-no-quantity";
                if ($child_location == 1) {
                    $child_quantity_block =
                        '<div class="quantity-container">
                    <input type="text" value="1" id="child-quantity-' . $child_option_id . '" class="qty-control" name="quantity" min="1" max="1">
                    <div class="increase button">+</div>
                    <div class="decrease button">-</div>
                </div>';
                    $child_quantity = 1;
                } else {
                    $child_quantity_block = "";
                    $child_quantity = "all";
                }

                $child_has_times = $resm_child_details->has_times;

                if ($child_has_times == 1) {
                    $child_time_counter++;
                    $child_time_data = json_decode($resm_child_details->time_data);

                    $child_departure_select = '<option value="-1">' . $mot[300] . '</option>';
                    $child_arrival_select = '<option value="-1">' . $mot[301] . '</option>';

                    $child_departures = $child_time_data->departures;
                    $child_arrivals = $child_time_data->arrivals;

                    foreach ($child_departures as $child_dep_key => $child_departure) {
                        $child_departure_select .= '<option value="' . $child_dep_key . '">' . $child_departure . '</option>';
                    }

                    foreach ($child_arrivals as $child_arr_key => $child_arrival) {
                        $child_arrival_select .= '<option value="' . $child_arr_key . '">' . $child_arrival . '</option>';
                    }

                    $child_departure_block = '<div class="col-half time-select-' . $child_option_id . '" style="padding-right: 0;">
                <select class="form-control time-departure" style="text-align: center;">' . $child_departure_select . '</select>
                </div>';

                    $child_arrival_block = '<div class="col-half time-select-' . $child_option_id . '" style="padding-left: 0;">
                <select class="form-control time-arrival" style="text-align: center;">' . $child_arrival_select . '</select>
                </div>';

                    $child_time_block = '<div class="row time-container">
                ' . $child_departure_block . $child_arrival_block . '
            </div><small class="error-message time-error">' . $mot[302] . '</small>';
                } else {
                    $child_time_block = '';
                }

                $child_host_cost_display = "";
                $child_extra = $resm_child_details->extra;
                $child_host_extra = $resm_child_details->host_extra;
                $child_host_class = "";

                if ($child_extra == 1) {
                    $child_extra_cost_1 = $resm_child_details->{"cost" . $currency . "_1"};
                    $child_extra_cost_2 = $resm_child_details->{"cost" . $currency . "_2"};

                    $default_child_extra = $host_price == 0 ? $child_extra_cost_2 : $child_extra_cost_1;
                    $child_cost_info = $mot[101] . ' : +<span class="extra-cost">' . number_format($default_child_extra, 2, ",", " ") .
                        "</span>" . $currency_symbol . " - " . $mot[102] . ' : +<span class="child-cost">0.00</span>' . $currency_symbol;

                    $child_host_class = " extra-option";
                }
                if ($child_host_extra == 1) {
                    $child_host_cost_display =
                        '<span class="host-cost">' . $mot[500] . ' : +<span class="host-price">0.00</span>' . $currency_symbol .
                        "</span><br>";
                }

                // Add the child option to the template
                $TEMPLATE->SET_BLOCK_VARIABLES("Block_OPTIONS.Block_OPTIONS_CHILD", [
                    "ID" => $child_option_id,
                    "QUANTITY" => $child_quantity,
                    "LABEL_CLASS" => $child_label_class,
                    "ACTION_CLASS" => $child_action_class,
                    "LABEL" => $child_label,
                    "DESCRIPTION" => $child_description,
                    "QUANTITY_BLOCK" => $child_quantity_block,
                    "COST_INFO" => $child_cost_info,
                    "HOST_COST_DISPLAY" => $child_host_cost_display,
                    "COST" => $child_cost,
                    "CHILD_COST" => $child_extra_cost,
                    "LOCATION" => $child_location,
                    "CATEGORY" => $child_category,
                    "HOST_CLASS" => $child_host_class,
                    "EXTRA" => $child_extra,
                    "HOST_EXTRA" => $child_host_extra,
                    "TIME_CHECKED" => ($child_has_times == 1) ? 'selected="' . $child_option_id . '" checked="true"' : '',
                    "TIME_BLOCK" => $child_time_block
                ]);

                $resm_sibling_data = $data_source->fetchData("parent=" . $parent_option_id);
                foreach ($resm_sibling_data as $sibling_key => $sibling_value) {
                    $sibling_option_id = $sibling_value->option_id;
                    $resm_sibling_details = $detail_source->fetch($sibling_option_id);
                    if ($resm_sibling_details) {
                        $sibling_label = $resm_sibling_details->{"label$lang"};
                        $sibling_description = $resm_sibling_details->{"description$lang"};
                        $sibling_category = $resm_sibling_details->category;

                        // Process cost for sibling category
                        if ($sibling_category == 0) {
                            $sibling_cost = $resm_sibling_details->{"cost" . $currency};
                            $sibling_extra_cost = $resm_sibling_details->{"sibling_cost" . $currency};
                            $sibling_cost_info =
                                $mot[101] . " : +" . number_format($sibling_cost, 2, ",", " ") . $currency_symbol . " - " .
                                $mot[102] . " : +" . number_format($sibling_extra_cost, 2, ",", " ") . $currency_symbol;
                        } elseif ($sibling_category == 1) {
                            $sibling_cost = $resm_sibling_details->{"cost" . $currency};
                            $sibling_extra_cost = 0;
                            $sibling_cost_info = $mot[101] . " : +" . number_format($sibling_cost, 2, ",", " ") . $currency_symbol;
                        } elseif ($sibling_category == 2) {
                            $sibling_cost = 0;
                            $sibling_extra_cost = $resm_sibling_details->{"sibling_cost" . $currency};
                            $sibling_cost_info = $mot[102] . " : +" . number_format($sibling_extra_cost, 2, ",", " ") . $currency_symbol;
                        } elseif ($sibling_category == 4) {
                            $sibling_cost = $resm_sibling_details->{"cost" . $currency};
                            $sibling_extra_cost = 0;
                            $sibling_cost_info = $mot[500] . " : +" . number_format($sibling_cost, 2, ",", " ") . $currency_symbol;
                        } elseif (
                            $resm_sibling_details->{"cost" . $currency} == 0 and
                            $resm_sibling_details->{"sibling_cost" . $currency} == 0
                        ) {
                            $sibling_cost = 0;
                            $sibling_extra_cost = 0;
                            $sibling_cost_info = "";
                        } else {
                            $sibling_cost = $resm_sibling_details->{"cost" . $currency};
                            $sibling_extra_cost = 0;
                            $sibling_cost_info = $mot[200] . " : +" . number_format($sibling_cost, 2, ",", " ") . $currency_symbol;
                        }

                        $sibling_location = $resm_sibling_details->location;
                        $sibling_label_class = $sibling_location == 1 ? "has-quantity" : "no-quantity";
                        $sibling_action_class = $sibling_location == 1 ? "active-with-quantity" : "active-no-quantity";
                        if ($sibling_location == 1) {
                            $sibling_quantity_block =
                                '<div class="quantity-container">
                    <input type="text" value="1" id="sibling-quantity-' . $sibling_option_id . '" class="qty-control" name="quantity" min="1" max="1">
                    <div class="increase button">+</div>
                    <div class="decrease button">-</div>
                </div>';
                            $sibling_quantity = 1;
                        } else {
                            $sibling_quantity_block = "";
                            $sibling_quantity = "all";
                        }

                        $sibling_has_times = $resm_sibling_details->has_times;

                        if ($sibling_has_times == 1) {
                            $sibling_time_counter++;
                            $sibling_time_data = json_decode($resm_sibling_details->time_data);

                            $sibling_departure_select = '<option value="-1">' . $mot[300] . '</option>';
                            $sibling_arrival_select = '<option value="-1">' . $mot[301] . '</option>';

                            $sibling_departures = $sibling_time_data->departures;
                            $sibling_arrivals = $sibling_time_data->arrivals;

                            foreach ($sibling_departures as $sibling_dep_key => $sibling_departure) {
                                $sibling_departure_select .= '<option value="' . $sibling_dep_key . '">' . $sibling_departure . '</option>';
                            }

                            foreach ($sibling_arrivals as $sibling_arr_key => $sibling_arrival) {
                                $sibling_arrival_select .= '<option value="' . $sibling_arr_key . '">' . $sibling_arrival . '</option>';
                            }

                            $sibling_departure_block = '<div class="col-half time-select-' . $sibling_option_id . '" style="padding-right: 0;">
                <select class="form-control time-departure" style="text-align: center;">' . $sibling_departure_select . '</select>
                </div>';

                            $sibling_arrival_block = '<div class="col-half time-select-' . $sibling_option_id . '" style="padding-left: 0;">
                <select class="form-control time-arrival" style="text-align: center;">' . $sibling_arrival_select . '</select>
                </div>';

                            $sibling_time_block = '<div class="row time-container">
                ' . $sibling_departure_block . $sibling_arrival_block . '
            </div><small class="error-message time-error">' . $mot[302] . '</small>';
                        } else {
                            $sibling_time_block = '';
                        }

                        $sibling_host_cost_display = "";
                        $sibling_extra = $resm_sibling_details->extra;
                        $sibling_host_extra = $resm_sibling_details->host_extra;
                        $sibling_host_class = "";

                        if ($sibling_extra == 1) {
                            $sibling_extra_cost_1 = $resm_sibling_details->{"cost" . $currency . "_1"};
                            $sibling_extra_cost_2 = $resm_sibling_details->{"cost" . $currency . "_2"};

                            $default_sibling_extra = $host_price == 0 ? $sibling_extra_cost_2 : $sibling_extra_cost_1;
                            $sibling_cost_info = $mot[101] . ' : +<span class="extra-cost">' . number_format($default_sibling_extra, 2, ",", " ") .
                                "</span>" . $currency_symbol . " - " . $mot[102] . ' : +<span class="sibling-cost">0.00</span>' . $currency_symbol;

                            $sibling_host_class = " extra-option";
                        }
                        if ($sibling_host_extra == 1) {
                            $sibling_host_cost_display =
                                '<span class="host-cost">' . $mot[500] . ' : +<span class="host-price">0.00</span>' . $currency_symbol .
                                "</span><br>";
                        }

                        // Add the sibling option to the template
                        $TEMPLATE->SET_BLOCK_VARIABLES("Block_OPTIONS.Block_OPTIONS_CHILD", [
                            "ID" => $sibling_option_id,
                            "QUANTITY" => $sibling_quantity,
                            "LABEL_CLASS" => $sibling_label_class,
                            "ACTION_CLASS" => $sibling_action_class,
                            "LABEL" => $sibling_label,
                            "DESCRIPTION" => $sibling_description,
                            "QUANTITY_BLOCK" => $sibling_quantity_block,
                            "COST_INFO" => $sibling_cost_info,
                            "HOST_COST_DISPLAY" => $sibling_host_cost_display,
                            "COST" => $sibling_cost,
                            "SIBLING_COST" => $sibling_extra_cost,
                            "LOCATION" => $sibling_location,
                            "CATEGORY" => $sibling_category,
                            "HOST_CLASS" => $sibling_host_class,
                            "EXTRA" => $sibling_extra,
                            "HOST_EXTRA" => $sibling_host_extra,
                            "TIME_CHECKED" => ($sibling_has_times == 1) ? 'selected="' . $sibling_option_id . '" checked="true"' : '',
                            "TIME_BLOCK" => $sibling_time_block
                        ]);
                    }
                }
            }
        }
    }
}
[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

by Remy Porter at August 27, 2026 06:30 AM

August 26, 2026

ISO C++

CppCon 2026 CMake: Making Hard Things Easy -- Bill Hoffman

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

CMake: Making Hard Things Easy

Wednesday, September 16, 2026 16:45 - 17:45 MDT

by Bill Hoffman

Summary of the talk:

Modern C++ development involves much more than compiling source files. Cross-platform builds, dependency management, C++ modules, package metadata, SBOM generation, CI infrastructure, and distributed builds have all increased the complexity of software engineering over the last two decades.

CMake has evolved alongside those challenges.

This talk explores how modern CMake helps make difficult software-engineering problems more manageable through targets, dependency modeling, metadata generation, debugging tools, and scalable build orchestration.

We will examine how CMake supports C++20 modules, including dynamic dependency scanning, build graph updates, and import std.

We will also look at CPS and SBOM generation together: CPS provides machine-readable package metadata, while SBOM support helps CMake expose software supply-chain information from the dependency graph.

Next, we will discuss debugging CMake itself using the CMake debugger protocol, and debugging builds using the CMake Instrumentation API to understand where time is spent during configuration and build execution.

Finally, we will examine distributed execution and build acceleration, exploring options available to CMake users in both open-source and commercial environments.

Along the way, we will discuss the real-world challenges, trade-offs, and lessons learned from evolving a long-lived build system to meet the demands of modern C++ development.

This is not your mother’s CMake.

by Blog Staff at August 26, 2026 07:11 PM

The Daily WTF

CodeSOD: Lock 'Em Dead

Kevin sends us an exception handler from C++. Let's see if we can spot what's going wrong:

catch (Exception::Deadlock)
{
   retry;
}

When we catch a deadlock happening, we retry. That's not a keyword in C++, and looking at how it's used, it has to be some kind of macro, and I suspect that the macro is hiding a goto underneath it.

The real problem, though, is that we suspect we're in a deadlock situation. That means this thread is waiting on a resource held by another thread which is waiting for a resource held by this thread. Neither train may continue until the other has passed. So this retry only works if it releases the resource held by this thread (letting the deadlocking thread proceed). But does it?

Not according ot Kevin. The code already had a pile of deadlocks in it, so they brought in a highly paid consultant to try and fix them by reordering access and tracing where mutexes were causing issues. This retry just jumps back up to the top of the block, without releasing any resources. It "seems the consultant wanted to add some deadlocks of their own," Kevin says.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

by Remy Porter at August 26, 2026 06:30 AM

XKCD

August 25, 2026

ISO C++

Trip report: ACCU On Sea 2026 -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGOnce again, I got the chance to come to Folkestone, UK. I think this was my fifth time, but the first one at ACCU On Sea. Yes, there is no more C++ On Sea, there is no more ACCU in Bristol — they got merged into ACCU On Sea.

Trip report: ACCU On Sea 2026

by Sandor Dargo

From the article:

he venue is the same as C++ On Sea, many organisers are the same, but of course there are also changes. The conference chair is no longer Phil Nash but Guy Davidson. The schedule is more packed — this year, the conference ran over four days (ignoring the two workshop days), including Saturday. Probably due to the fact that these two major C++ conferences were merged, I think there were more people than ever — around 400 C++ enthusiasts. It was sold out.

And yet, in general, familiar faces. This place holds a special place in my heart as it was the first in-person international C++ conference which I attended as a speaker.

In this post I’ll share:

  • Highlights from talks and ideas that resonated with me.
  • Personal impressions, including reflections on my own sessions — both the main talk and the lightning talk.

I’ll update this article with links to the recordings as soon as they become available.

by Blog Staff at August 25, 2026 09:00 PM

The Daily WTF

Representative Line: Both Ways Bug Me

There are many cases where some sort of debugging block sneaks by, especially cases where we see preprocessors or templates working, which leave us with nonsense like if (true == false) running in production. But Codemonkey found a new twist on that sort of thing, in a SQL query being run in production.

WHERE (some conditions) AND (1 = 0 OR (1 = 1 AND (other conditions)))

The OR means that by twiddling the first equality check, we can toggle "always return rows" with "return based on condition". Toggling the second we can make it "never return rows", which I'm not certain is actually useful. I can see how these likely did start life as debugging flags, but they're still weird, still unnatural. They point to some other problem in observability in the code. And, as all "good" flags go, they're not documented anywhere, this seems like it started life as a query an analyst was running until it got turned into stored procedure to be run again and again. The flags have never been changed since the code was released, as far as anyone can tell.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!

by Remy Porter at August 25, 2026 06:30 AM

August 24, 2026

ISO C++

CppCon 2026 AI is UB with Better PR -- Matt Kulukundis & Andy Soffer

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

AI is UB with Better PR

Wednesday, September 16, 2026 15:15 - 16:15 MDT

by Matt Kulukundis & Andy Soffer

Summary of the talk:

C++ runs the world’s systems, and with that comes a responsibility for safety and stability. Avoiding AI entirely gives up on incredible potential benefits, but using AI without guardrails poses significant risks to our critical systems. How does AI fit into this world? This talk examines effective and ineffective approaches to using AI in systems that cannot afford “slop.” We will explore several case studies where AI produced significant value in C++, and several where it did not. The pattern that emerges is consistent: AI thrives when it is orchestrating well-defined, deterministic components, translating between them intelligently without being trusted to reason correctly on its own. When AI is asked to be the system rather than connect the system, things fall apart.

by Blog Staff at August 24, 2026 07:09 PM

The Daily WTF

RCE As a Feature

The opposite of meritocracy is kakistocracy: the worst and least-qualified are the ones who rise to the top.

Get real familiar with that word, dear readers. I think you'll need it.

If anyone can back me up on this, it's our submitter, Jared B:

Time Magazine cover April 3, 2017

I am a teacher by profession, and worked for a year at an ed-tech company founded by a mechanical engineering professor, Harry. Harry had spent a great deal of time in the 90's developing a C interpreter (yes, you read that right). 30 years later, he remained convinced that his interpreter was the technology of the future, and had founded a company that offered math and computer science curriculum to K-12 students based on C programming.

Originally, he had written a textbook that introduced students to programming using a locally-installed version of his interpreter and custom IDE. A little vain, but no serious problems. As Chromebooks grew popular in schools, he had developed a web IDE where students could write and run C code.

But Harry could never give fully give up on the Windows IDE for his C interpreter. So, he included in the web version a "Run Locally" button for those school computers still running Windows. It worked like so: installing the interpreter and IDE locally would also install a daemon that activated on startup and ran a websocket server. This server had an endpoint which accepted as a parameter a string of C code. It would then pass this C code to the locally-installed interpreter to run.

As you might suspect, there was no authentication whatsoever on this local websocket server. Knowing the form of the protocol, ANY domain could connect to localhost:12345/execute_c_program and send arbitrary code to run (of course, Harry prided himself on the completeness of his C implementation, including execv() and the like). Trick a user into visiting a malicious website, and you automatically had RCE on their computer.

Adding insult to injury, I discovered that the server was bound to 0.0.0.0 so that if you had Harry's software (/malware) installed, any computer on the same network as you could send you arbitrary C code to execute without question.

These vulnerabilities had existed for several years before I joined the company. In all that time, Harry had never hired anybody but his own grad students as software developers, and none of them had noticed the problem. By that time, the software was installed on thousands of school-owned computers throughout the state.

I documented and demonstrated the vulnerabilities to Harry. He did release a new version of the software addressing the issues and citing "security improvements" in the release notes, but there was never a communication to school/district IT leaders to describe the importance of updating. I suspect that Harry should be in serious legal trouble for potentially compromising data related to schools and minors, but I've since moved on and dropped the subject.

During the year I spent at the company (not in any sense as a dev, mind you, but as a lowly curriculum writer), I also discovered and reported a cookie-stealing exploit that would have compromised student and teacher data, as well as a code injection on another of Harry's websites (he decided to demonstrate that his C interpreter could work as a web server via a page where a user could type a math expression, which was then eval()ed server-side without any sanitation). The latter vulnerability gave me remote access, where I discovered thousands of transaction records that included credit card information stored in the clear.

Harry's company is still in business to this day, and has recently been ranked in TIME's list of top American ed-tech companies. Oh, and the office router's admin page still had the default Google-able username and password, but that one's a freebie.

I knew someone like this once, only they were stuck on ColdFusion long after everyone else stopped caring about it. However, I don't think they went on to endanger an entire state's educational system, only to be lauded as a visionary leader. Can't say for sure, though.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

by Ellis Morning at August 24, 2026 06:30 AM

XKCD

August 21, 2026

The Daily WTF

Error'd: Hello, New Mexico!

Peter G. shared with us yet another ordering bungled example of. "Should really say "please engage in an Easter egg hunt to find your language"."

3ccdf44218264528b28550518f7d6aea

"Google can't count" claimed Peter S.. It adds up. "Yet another proof that 0=1, this time from Google."

2d284d0f696d48669a9c59251ecf9bc0

"Thanks, Microsoft" groused Ivan "Ever since Microsoft ate university e-mail services worldwide and became responsible for major free software mailing lists, quality of service has been steadily dropping. In order to report delivery problems to Outlook, you need a Microsoft account. You're prevented from creating it at first because of "suspicious activity". Once you're in, the contact address is pre-filled for you with an invalid email. Once you fix that in the web developer toolbar, fuck you anyway! I think the form isn't actually expected to work; the fact that the request was submitted is an error. The only thing missing from the experience is the "beware of the leopard" sign."

ae9ba09cc9474a2f89b8358201b0419a

"Mango Math" needs a bit of money math for the rest of the world to understand. Michael R. muttered "I will buy it by the slice then." The joke here is on the tip of my tongue. Explainer: the new pence is one hundredth of the decimal pound. No shillings no more, decreps! At that ratio, 3p per slice of cheesecake would indeed be far less dear than four pounds for the whole thing, barring translucent slices. Alas, the reality is simply the boring fact that the price is 3p per gram. Not as funny but I'm chuckling imagining Michael's transparent serving of diet cheesecake. I'll leave it up to you to decide if a gram really counts as an "item".

bd6d8a538f7a45b2a81f8b52d425b180

Clint clucked "Got this email from Bigbadtoystore. Lots of links available for preorder!" I think the talented website builders behind the New Mexico DOT have been busy.

d7efd5aabe754173a54fccb84c60b942

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

by Lyle Seaman at August 21, 2026 06:30 AM

Error'd: Failure, After Failure, After Failure...

We have a couple from Foo (AKA Foo) today, include a special text copy-paste

Foo shared "I know you usually post image WTFs here, but here's a text output from chromium:

[...:ERROR:components/viz/service/display/display.cc:273] Frame latency is negative: -0.18 ms

While this issue might be fixed by now, at least on some platforms, I think it's remarkable that someone actually wrote this message without wondering if it ever makes sense ...

And also commented "I visited Spain to see the eclipse (which was great BTW). I had heard that temperature may drop during totality, but was surprised by how much." Negative Infinity!

0be1027004e44b13bd405c187d01c644

"Youfailedatmathtube" muttered dragoncoder047, snarking only "Title."

afc0394174854c19aaa86bbee370f978

"Hello to you too, New Mexico!" enthused Chris A. "Setting up web sites is hard. The DOT got bored half way through and just left the rest of the buttons as they were."

fbe8150c963d4abaac4897bf083e1992

Finally, "Failure Fail" from Basti "Did I succeed or did I fail? Is my whole life a success? Or a failure? I'm confused. You can find this here.

fc74a13838f6458587db51bd80405415

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

by Lyle Seaman at August 21, 2026 06:30 AM

XKCD

August 20, 2026

ISO C++

CppCon 2026 In Pursuit of a 6,000 FPS Game Boy Emulator -- Tom Tesch

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

In Pursuit of a 6,000 FPS Game Boy Emulator

Wednesday, September 16, 2026 14:00 - 15:00 MDT

by Tom Tesch

Summary of the talk:

How far can modern C++ push an emulator before performance stops being a C++ problem and becomes a systems problem? This talk is the final part of a CppCon trilogy about building an extremely fast Game Boy emulator in modern C++, moving from high-performance emulation techniques to the limits imposed by hardware, compilers, and CPU architecture.

The target is intentionally absurd but not arbitrary: a Game Boy emulator running Tetris at roughly 100 times original speed, about 6,000 frames per second. However, the goal is not to support every Game Boy cartridge ever made. This project deliberately specializes for one iconic game first, using the code paths Tetris actually exercises as a guide, while keeping enough design discipline to test other games later. That means questioning the architecture of the emulator itself: instruction dispatch, memory access, generated code size, cache behavior, branch prediction, compile-time computation, benchmarking methodology, and the tension between accuracy, maintainability, flexibility, and raw throughput.

This is not a victory-lap performance talk. It is a measurement-driven engineering investigation. Rather than treating 6,000 FPS as just a headline number, this talk treats it as a stress test: a way to force difficult design decisions into the open. Attendees will leave with concrete lessons about performance-oriented C++: how to measure methodically, how to specialize without losing control, how to reason about modern CPU behavior, and how to decide when an optimization is worth its cost.

by Blog Staff at August 20, 2026 07:05 PM

The Daily WTF

Representative Line: We All Register This

Today's maybe more of a "representative data sheet entry" than anything else.

Every developer has the experience of reading the documentation. If you've been at this for some time, you've probably read bad documentation. Documentation that is incomplete, inaccurate, or otherwise flawed. Or, my personal favorite, the brief time where Oracle tried to put all of its documentation into an Adobe Flex site (aka, a Flash application, not a real web app). That one had fun bonus features, like "breaking copy and paste" and "preventing you from deep linking to a piece of the documentation".

But software documentation has got nothing on bad data sheets. When you buy an integrated chip from a vendor, whether it's a microcontroller that'll run your code, a sensor you're trying to get data from, you're at the mercy of the datasheet for understanding how it works. Sometimes, even finding an English language datasheet can be a challenge. The more complex the chip you're trying to interact with, the more complex the datasheet needs to be, and at a certain point, a lot of vendors say, "meh, you'll figure it out." I've had chips where the datasheet and reality disagreed about what registers were available, which often means that core functions of the chip require twiddling undocumented registers. For more fun, they sometimes lie about which pins on the chip do which thing, including mislabeling which pins handle power. There's nothing more fun than the tiny little "pop" of a chip dying when you throw 5V power onto a pin that's actually ground.

Now, there are some vendors, and some products, where the datasheets are pretty solid. This isn't a universal problem, but when you're working in an embedded space, "cheapest" is frequently the main criteria for picking components, and "cheapest" means "worst documented".

Which brings us to Jarek's recent experience going through a data sheet. The chip in question had a "fantastic feature" that would change how debugging worked, which was for "super users" to enable by setting a register.

3.2.4 Super User Fantastic Feature Enable Register
The Super User Fantastic Feature Enable Register allows the user to modify the behavior of the mEDBG.
Name: SUFFER
Offset:  0x0120
Reset: 0xFF

Sometimes, doing embedded work definitely feels like the SUFFER register is set.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

by Remy Porter at August 20, 2026 06:30 AM

August 19, 2026

ISO C++

Dispatch Table with C++26 Reflection - Zero Boilerplate & Zero Runtime Overhead -- NoqtaBeda

avatar.jpgDispatch tables are a common way to map names to functions, but traditional C++ implementations inevitably involve either repetitive boilerplate or runtime initialization. C++26's static reflection opens the door to a fundamentally different approach, allowing the compiler to discover functions, build the dispatch table, and optimize its representation entirely at compile time.

Dispatch Table with C++26 Reflection - Zero Boilerplate & Zero Runtime Overhead

by NoqtaBeda

From the article:

As compile-time reflection is finally adopted to C++26 standard, developers are enabled to fetch and operate on the metadata of the C++ program itself. Metadata of various C++ entities (variables, functions, classes, templates, namespaces, etc.) can be obtained from reflection API in C++26 standard library, the most frequently used of which is getting an entity’s name, type, list of members or list of base classes. Reflection is incredibly helpful to support more elegant and more efficient C++ code by utilizing the metadata properly. In this blog we dive into dispatch table, which is a common pattern in real-world C++ code, demonstrating how the great power and expressiveness of C++26 reflection helps with eliminating boilerplate code and runtime overhead that are inevitable in pre-C++26 dispatch table implementation, and then, how the API design of our reflection-based dispatch table can be further improved step-by-step.

The contents shown by this blog has full implementation in my rbox library. Source code is available in GitHub.

How It Works Finally

We start from the following example to demonstrate the expressiveness of C++26 reflection. All the constexpr evaluations of building the dispatch_table are encapsulated into the API macro RBOX_FUNCTION_FIXED_MAP. The first parameter ops is the namespace whose members are to be traversed. The second parameter "do_*" is the identifier pattern which the members of namespace ops are expected to follow. Each function in namespace ops is added to the dispatch table if and only if its identifier matches the pattern "do_*". The dispatch_table returned is an associative array whose value type is auto-deduced as int (*)(int, int) and the internal data structure is selected adaptively according to the input (typically a hash table, or a linear table as fallback when the number of entries is few).

by Blog Staff at August 19, 2026 08:57 PM

The Daily WTF

CodeSOD: Back to the Lab

Matlab is special. Scientists and researchers love it. Programmers hate it, and not just because it uses 1-based arrays. I've worked on a number of projects where the task was "take this Matlab code and convert it to C so we can run it on an embedded CPU". Somehow, in that process, I've avoided learning much about Matlab.

Andre works on a team that uses Matlab to manage experimental scenarios. They wanted to do a simple task: generate a set of participant-specific images, store them in a database, and reference them later. Somewhere in the intersection of the database product they were using, the Matlab license they had, and other constraints, they discovered that there simply was no good way to do this.

Enter "Jude". Jude said, "Don't worry about it, I can hack something together."

I present the code in its entirety, but don't ask me to explain it. Instead, read the comments.

nMk = 1;%counting non-response triggers, this cycles with each trial
nPress = 0;%counting button presses, noting the position in the log

for v = 1:height(resVmrk)%read each trigger
	switch nMk
		%it's kinda roundabout, but the only recognisable part is the response
		%yet I refer to it only by elision
		%and instead count the stimuli to reconstruct the pattern
		case 1%an almost reliable stimulus
			nPress = nPress+1;%trial start
			if strcmp(resVmrk.TriggerCode{v},'S1')%it must be a non-response
				resVmrk.TriggerCode{v} = 'cross';%name it properly
				nMk = 2;%and expect the next one
			else%except when it is not
				resLog.miss(nPress) = 1;%then note it down as missed
				nMk = 0;%and skip to response
			end
			
		case 2%usually reliable
			if strcmp(resVmrk.TriggerCode{v},'S1')%if the face loaded successfully
				resVmrk.TriggerCode{v} = 'face';%note it
				nMk = 3;%and proceed accordingly
				if nPress<=height(resLog)%trailing triggers at the end should be ignored
					resLog.facePos(nPress) = v;%note the position
				end
			else%if it failed to load it is a response
				resVmrk.Dur(v-1:v+1) = 0;%mark the whole trial for deletion
				resLog.miss(nPress) = 1;%and note it down as missing the face
				nMk = 0;%and skip to response
			end
			
		case 3%this one is not reliable, and sometimes is duplicated instead of missing
			if strcmp(resVmrk.TriggerCode{v},'S1')%if it is present at all
				resVmrk.TriggerCode{v} = 'empty';%first name it
				if v<height(resVmrk)%if it is not a trailing trigger, since it'll break the check otherwise
					if ~strcmp(resVmrk.TriggerCode{v+1},'S1')%if the next trigger is a response
						nMk = 0;%all is fine and it didn't freak out, proceed to response
					else%otherwise
						nMk = 3;%just treat as a double
						%and then count how many excess triggers are actually here
						nExcess = 1;%definitely one here already
						while strcmp(resVmrk.TriggerCode{v+nExcess+1},'S1')
							nExcess = nExcess+1;%and everything until the response
						end
						resVmrk.Dur(v-2:v+nExcess+2) = 0;%then mark the whole trial for deletion
						%this overwrites the same positions several time, but the important part is to get the preceding two, because I don't know which one of them is correct one, so I delete the whole trial
						if nPress<=height(resLog)
							resLog.bad(nPress) = 1;%also note it down as borked
						end
					end
				end
			else
				nMk = 0;%if it didn't happen at all simply proceed to response
			end
			
		case 0%this one reliably follows the response, so I address the response by elision
			if strcmp(resVmrk.TriggerCode{v},'S1')%skip response itself
				resVmrk.TriggerCode{v} = 'blink';%note the only reliable non-response (always following the response)
				nMk = 1;%start the trial anew
				if nPress<=height(resLog)%if it is not a trailing trigger
					resLog.respPos(nPress) = v-1;%note down the response position
					if resLog.miss(nPress)==1%and if it's a response without a stimulus
						resVmrk.Dur(v-1:v) = 0;%mark it for deletion as well
					end
				end
			end
	end
end

Ah, the classic "for-case" antipattern. That's gross enough, but what the heck is happening inside each of those cases?

My personal favorite comment is this one: "%this overwrites the same positions several time, but the important part is to get the preceding two, because I don't know which one of them is correct one, so I delete the whole trial"

Now, you may suspect comments like "usually reliable" are about what we see in the dataset, but I'm not so certain. Andre writes:

After reverting the last discovered way for his creation to corrupt the data I was able to figure out that 20% of the logs provided corresponded to different (unknown) experiments altogether.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

by Remy Porter at August 19, 2026 06:30 AM

XKCD

August 18, 2026

ISO C++

CppCon 2026 Awaiters and Awaitables -- Mateusz Pusz

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

Awaiters and Awaitables

Wednesday, September 16, 2026 09:00 - 10:00 MDT

by Mateusz Pusz

Summary of the talk:

C++20 coroutines come with a reputation for complexity — and writing your own coroutine return type deserves that reputation. But here is the good news: you probably don't have to. With std::generator in C++23, high-quality libraries like Asio and cppcoro today, and std::task on its way in C++26, most developers can simply write co_await and move on.

There is one gap, however. Sooner or later, every developer using coroutines needs to bridge an existing asynchronous interface — a timer, an I/O operation, a thread pool callback, a legacy future — into the coroutine world. That bridge is built with awaiters and awaitables, and that is exactly what this session teaches.

We will start from first principles: what does co await actually do? We will demystify the three functions that form the awaiter protocol — await ready, await suspend, and await resume — and build a clear mental model for each. We will implement a real awaiter from scratch, then explore how symmetric control transfer keeps the call stack flat across deeply chained async operations. Next, we will learn how to make any existing type co await-able without modifying it, using operator co await, and how await transform lets you restrict or adapt awaitable behavior to a specific coroutine context. Finally, we will look at how to write cancellation-aware awaiters using std::stop token, so your coroutines respond promptly when work is no longer needed.

No prior coroutines experience is assumed. If you know what co await looks like on the surface but not what happens underneath it, this session is for you. You will leave with both the knowledge and the code to wrap any asynchronous operation into a first-class co await expression.

by Blog Staff at August 18, 2026 07:03 PM

The Daily WTF

Floating Along

Today's submitter John F. was migrating data from a Microsoft platform to a Microsoft platform, using Microsoft tools. Absolutely nothing could go wrong, right?

Right?

Lining up the decimal points

A few years ago, I was working on a migration. We had sold part of our business, and so we had to extract a whole bunch of customer documents and metadata to provide to the buyer. The documents were stored in SharePoint on-premises, so the first step was extracting the metadata and storing it in a SQL Server database.

A colleague had used Microsoft's ETL tool SSIS to get the process started, and it generated a database schema. But after taking over, I wanted to change to PowerShell for greater control. For speed reasons, I decided to use System.Data.SqlClient.SqlBulkCopy, and getting that going required making sure my PowerShell script had all the correct data types.

One of our fields was the customer number. Customer numbers were up to 10 digits, but the first two were usually 0. Now, I prefer storing customer numbers as text, but someone in the distant past thought, This is a number, and SharePoint has a Number field, so I will use that.

Under the hood, Number fields in SharePoint are actually Doubles. Using a Double to store something exact like a customer number is not really ideal, but double-precision is absolutely enough to represent 10 digit numbers accurately. So what went wrong?

Well, remember we used SSIS to create the original table schema in SQL Server. I then used this table schema to write my script. But it turns out that in SQL Server world, the double-precision type is called float. If you want single-precision, you have to say float(24). I didn't know this, and so when I saw the SQL Server column as a float, I entered float as the corresponding .Net type in my script.

Oops.

So numbers came out of SharePoint as double. They were then converted to float before being inserted into SQL Server. Almost all records were fine, but large customer numbers had their last few digits changed. Testers didn't notice, but fortunately someone picked it up in the full load. We had to generate a list of changed numbers to patch the data after the fact.

[Advertisement] Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.

by Ellis Morning at August 18, 2026 06:30 AM

August 17, 2026

ISO C++

Book Review: Memory Management in C++ by Patrice Roy -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGMemory management is one of those topics that every C++ developer has to deal with, yet very few of us take the time to study it systematically. Memory Management in C++ by Patrice Roy is a book that finally gives this fundamental topic the deep and up-to-date treatment it deserves. It covers everything from the basics of how objects live in memory to modern techniques introduced as recently as C++26.

Book Review: Memory Management in C++ by Patrice Roy

by Sandor Dargo

From the article:

What impressed me right away is how current the book is. It discusses erroneous behaviour, which is something that was only introduced in C++26. It also proposes the usage of deducing this as a way to reduce boilerplate in begin()/end() implementations. Finding a book that is both thorough in its foundations and aware of the latest developments is rare.

As Patrice writes, “C++ is powerful and flexible, but if you program in C++, you’re expected to behave responsibly and professionally.” This sentence sets the tone for the whole book. It’s not about dumbing things down or hiding complexity behind abstractions. It’s about understanding your tools well enough to use them correctly.

Let me highlight three ideas from the book that I found particularly valuable.

char* is not what you think it is

One of the most eye-opening sections deals with the true meaning of char*. Most of us think of char as a character type. But as Patrice explains, “char* means ‘pointer to a byte.’ Due to the C language roots of C++, a char* can alias any address in memory (the char type, regardless of its name, which evocates ‘character’, really means ‘byte’ in C and, by extension, in C++).”

This is not just a historical curiosity. It has real consequences for optimizations. “There is an ongoing effort in C++ to give char the meaning of ‘character,’ but as of this writing, a char* can alias pretty much anything in a program. This hampers some compiler optimization opportunities (it is hard to constrain or reason about something that can lead to literally anything in memory).”

by Blog Staff at August 17, 2026 08:55 PM

The Daily WTF

The State of Ticketing

Developing software can't simply be done with a text editor and a compiler. There are a variety of other tools we have to bring to bear that support our efforts and keep the team organized, like say, source control.

There are certain tools we all have to use that I would argue, nobody has actually make a version that's any good. Build tooling is one of my go-to examples: there are no good build systems, only build systems that are good enough for this task.

Another is ticket/task management. In fact, I'd go so far as to say, there are no good ticket management tools. Amongst the not good tools, I'd put Jira as one of the not goodest of all.

What makes Jira attractive to companies is the same thing that makes it miserable, and the thing that infects any "enterprise" software platform and turns it into garbage: it has all the features and expect you to build your own workflows with it. You don't merely use Jira, you have to program your own interfaces in Jira to get your workflow into the system. And if you have the misfortune to have a project manager who thinks they're more technical than they are, they'll endlessly spin up new views, new workflows, and rearrange how the work is tracked in lieu of actually working.

I've been on that team.

One of Jira's features is the ability to describe the ticket workflow: the state machine that describes your process from the initial entry of the ticket all the way down to released software or project completion. This includes routing, so that as one team member does their part of the work, it automatically goes to someone else to do the next portion of the work.

Which brings us to Klinsten. They were working on a new team, and wanted to change the ticket status from its current status to whatever came next in the workflow. So they looked at the workflow.

A Jira ticket workflow. There are a pile of states arranged in a column, and connected by arrows. So many arrows. It's impossible to tell which arrow connects which two states. A second version of the diagram is in the picture, with transition labels attached. It makes less sense. For bonus points, the labels are a mix of English and Dutch

These are two different versions of the same workflow, one with transition labels added, which as you can see, does nothing to clarify the workflow. That it's a mix of Dutch and English doesn't help matters.

The purpose of this workflow is to help the team understand how to sequence and organize their work. But this workflow has so many states and so many transitions, it fails at this goal. Looking at it makes me just want to gesloten my browser tab, because this user isn't accepting any of this.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

by Remy Porter at August 17, 2026 06:30 AM

XKCD

August 15, 2026

ISO C++

Deriving Type Erasure -- David Álvarez Rosa

A step-by-step derivation of the type-erasure idiom, building a minimal std::any from nothing but virtual functions and templates.

Deriving Type Erasure

by David Álvarez Rosa

From the article:

Ever looked at std::any and wondered what’s going on behind the scenes? Beneath the intimidating interface is a classic technique called type erasure: concrete types hidden behind a small, uniform wrapper.

Starting from familiar tools like virtual functions and templates, we’ll build a minimal std::any. By the end, you’ll have a clear understanding of how type erasure works under the hood.

by dalvrosa at August 15, 2026 06:52 PM

August 14, 2026

ISO C++

CppCon 2026 What Are We Synchronizing? -- Robert Leahy

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

What Are We Synchronizing?

Tuesday, September 15, 2026 14:00 - 15:00 MDT

by Robert Leahy

Summary of the talk:

Atomic memory ordering is often taught operationally: Use acquire here, release there, and perhaps add a fence “to be safe.” This approach tends to produce cargo-cult synchronization, where atomic operations are selected mechanically without a clear understanding of what information is actually being propagated between threads. In practice, memory ordering is not about memorizing enum values, but about establishing which facts become visible to which observers, and when.

This talk approaches atomic synchronization from first principles. Beginning with the fundamental ideas of publication, visibility, ownership transfer, and synchronization edges, the talk incrementally develops several concurrent structures drawn from real asynchronous systems. Case studies include outstanding-work reference counting, a multi-producer singly-linked publication structure, a concurrently-mutated doubly-linked intrusive list, and the coordination machinery underlying a concurrent operation with multiple concurrent completion modalities. Each structure is used to derive the synchronization requirements imposed by its invariants, rather than selecting memory orderings mechanically.

Along the way, the talk explores the practical meaning of relaxed operations, acquire/release synchronization, and atomic thread fences. Particular attention is paid to understanding what each actually does, when it is necessary, and when it has become a decorative synchronization cargo cult. The goal is not simply to present lock-free algorithms, but to develop a principled way of reasoning about memory visibility and synchronization in real concurrent systems.

by Blog Staff at August 14, 2026 06:42 PM

The Daily WTF

Error'd: Zero to Zero in 0 seconds

"So many zeroes! I'm in." W00H000! Kivi S. "found this ad in the wild. This must be a very large jackpot, look at all those zeroes!"

9bc39202c0254a468b610e65a50c4ab6

"I knew it!" groused an anonymous cynic. "Yes, SignUpGenius. We all know that SUCCESS is just an illusion."

e3080893822a416599d25e943913afd5

Another anonymous grouch reported "I guess JustWatch has suddenly become a bit precious about their sources"

458baffe588e4aa3ab4f4b9776fc0ef5

"These boots are made for crashing" thundered Michael R. "PII of the developer have been removed to protect the not so innocent." You can't hide PHP so easily.

7958aead3beb44579b149b2c75891bef

And again from prolific Michael R. "El Reg has been around for 30+ years and their code should be mature. I wonder about their SQL which seems to randomly return duplicate records. https://www.theregister.com/week". I'll be happy when Errord shows up on El Reg. Ok, no I won't but I'll at least be grouchy differently.

9489e6b6f15c4691828357c28262a628

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

by Lyle Seaman at August 14, 2026 06:30 AM

XKCD

August 13, 2026

ISO C++

Parsing JSON at compile time with C++26 static reflection -- Daniel Lemire

AdxWs-825x510.jpgPrograms often read configuration files at startup, even when those files never change after the program is built. With C++26, you can eliminate that entire step by having the compiler read, parse, and validate the configuration at compile time, leaving only the finished data in the executable.

Parsing JSON at compile time with C++26 static reflection

by Daniel Lemire

From the article:

Suppose that you have a configuration file in JSON. Something like this:

{ "width": 1920, "height": 1080, "fullscreen": true, 
"title": "My Game", "volume": 0.8 } 

Normally you ship this file alongside your program, open it at startup, read it, and parse it. That is a lot of work for data that never changes. What if the file is fixed at build time? Could the compiler read it, parse it, and bake the result directly into the executable as a constant?

With C++26, the answer is yes. We need two new ingredients, all of which are usable right now with the latest version of the GCC compiler (16).

  1. #embed to pull the file into the program at compile time,
  2. A software library supporting static reflection like simdjson.

Let me show you how far we can take this.

by Blog Staff at August 13, 2026 08:52 PM

The Daily WTF

August 12, 2026

ISO C++

CppCon 2026 Processor Design and C++ Memory Models -- Ofek Shilon

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

Processor Design and C++ Memory Models

Tuesday, September 15, 2026 09:00 - 10:00 MDT

by Ofek Shilon

Summary of the talk:

std::atomic and std::memory_order are utterly opaque abstractions. It feels like they were put in place to hide some monstrosity that is too complex for mortals to comprehend, and inevitably when trying to understand the underlying reality, the explanations end with 'the processor does weird things' and 'think about it as if...'.

Well, 'think about it as if' no more. In this talk we'll present the gory and wonderful mechanics of cache coherence protocols, store buffers, cache invalidation queues and the in-processor load-store-queue. We'll explain how modern hardware design makes different cores have different views of memory, and what fences and read-modify-write instructions do exactly - for both x86/64 and ARM/RISC-V (which are sometimes dramatically different).

This is an advanced low-level talk located at the borderline of software development and electrical engineering, discussing topics rarely - if ever - discussed at C++ conference talks.

by Blog Staff at August 12, 2026 06:39 PM

The Daily WTF

Branching Paths

"You submitted a pull request."

Indika was, in fact, reviewing the comments she'd gotten on that very same pull request, when her boss, Bill, walked up behind her. What she didn't understand is why Bill said it like it was an accusation.

"Yes?" she replied.

"Okay, well, we don't do that here. You're new, so I'll let it slide, but please review the developer guide."

Well, Indika had reviewed the developer guide, or at least thought she had. As it turned out, there was the official, company wide developer guide. That's the one she'd read. But Bill maintained his own, for his team. He hadn't ever told her about it, but apparently assumed she'd have the oracular blessings of Apollo and find it by herself.

It had this to say:

Branching is prohibited. Merging is a time wasting activity and goes against CI principles. Only use git to commit, push, and pull.

And rebase, presumably, if everyone was just committing on the main branch?

Indika asked one of her co-workers, Elise, over coffee: "Is this real?"

"Yeah," Elise said. "I'm not sure how he found out about your PR, I don't think anybody added him to the review. I mean, why would they?"

"Oh, I sent him the link," Indika said. "Just a whole, 'I'm new here, look at me doing the work!' type heads up."

"Oh yeah, definitely don't do that."

"So we do use PRs?"

Elise nodded. "Of course we do. We're not crazy. We just make sure Bill never finds out."

That seemed like a terrible way to work, but Indika went along with it, at least for a few weeks. Then an opportunity presented itself; she and Bill bumped into each other in the kitchenette grabbing coffee, and nobody else was around. At this point, Indika had already submitted a number of PRs without Bill knowing.

"Bill, I've been meaning to ask, what's your rationale for prohibiting branching?"

Bill loved being asked that question. "Well, well, it comes from twenty years of experience. What exactly does a branch get you?"

"A distinct history of changes that can be maintained and eventually merged in once a large unit of work has been done without disrupting other work that might be in flight?"

"Another point of conflict! A chance for the code you're working on to get stale. A chance to fall behind the rest of the team. Now, for a large open source team, with a lot of collaborators, a branch might make sense. I'm skeptical, but I can at least understand it. But for our internal team? It's just developers seeing a new toy and going, 'oh, shiny!'"

Indika sipped her coffee and went back to her desk. She was fortunate to have a window nearby, and looked at the squirrels playing in the branches of the tree.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!

by Remy Porter at August 12, 2026 06:30 AM

XKCD

August 11, 2026

ISO C++

C++26: Cleaning up string literals -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGThe two papers we are covering today are complementary in a philosophical sense. They both improve how string literals are handled in C++26. P2361R6 tackles strings that are never evaluated — the ones that only exist at compile time. P1854R4 tackles evaluated string literals, making non-encodable characters ill-formed instead of implementation-defined. Let’s start with the unevaluated side.

C++26: Cleaning up string literals

by Sandor Dargo

From the article:

Not all string literals in C++ end up in your compiled program. Some are used exclusively at compile time — the compiler reads them, acts on them, and then they’re gone. They never make it into the binary.

These strings appear in the following contexts:

  • _Pragma directives
  • #line directives
  • [[nodiscard]] and [[deprecated]] attributes
  • extern linkage specifications
  • asm statements
  • static_assert messages
  • Literal operator names

Since these strings are never evaluated at runtime, they don’t need to be converted to the execution encoding or any encoding specified by a prefix like L, u8, u, or U. Despite this, before C++26, the standard didn’t formally distinguish them from regular string literals. Compilers handled them inconsistently.

 

by Blog Staff at August 11, 2026 08:50 PM

The Daily WTF

CodeSOD: Public Private Partnership

Eric O was trawling through an API for handling concurrency, and found this little mismatch between the comment and the definition:

/// <summary>
/// private Status, because while this object needs to be able to set the status, consumers should only be able to check it, lest everything break.
/// </summary>
public StatusType Status {
    get {
        return _status;
    }
    set {
        if (value != _status) {
            RaisePropertyChanged("Status");
        }
    }
}

It's very important we make this property private, lest clients abuse it, and unleash dragons, chaos, and other potential horrors. Given that this happens inside of a concurrency API, I can only imagine what could go wrong when you mess this up. So sure, the comment makes sense.

The definition on the other hand, doesn't agree.

In practice, it's probably fine to do it this way, and at least the comment will show up in the documentation. If a consumer of the API misbehaves, they'll at least see that the docs suggest this is private.

The joke, of course, is the idea that the users of the API are going to read the docs, or care that one of the public methods suggests that it should be private.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

by Remy Porter at August 11, 2026 06:30 AM

August 10, 2026

ISO C++

CppCon 2026 The Journey to "/W4 /WX": How Hard Could It Be? -- Keith Stockdale

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

The Journey to "/W4 /WX": How Hard Could It Be?

Monday, September 14, 2026 15:15 - 16:15 MDT

by Keith Stockdale

Summary of the talk:

Building on the recent work of improving the quality of Sea of Thieves' codebase by upgrading from C++14 to C++20, this talk will focus on the work that has went into enabling warnings as errors on the game, and more.

Rare will discuss the motivations behind wanting to crank up the warning level, and to flick the "warnings as errors" switch after 10 years of development in their multi-million line Unreal Engine code base.

What were the challenges? How much effort did it take? Was it worth it? Did we find any bugs? Did we stop at just "/W4 /WX"? What warnings did we find the most useful? What warnings were deemed unhelpful? All of these questions and probably more will be answered throughout this session.

by Blog Staff at August 10, 2026 06:36 PM

The Daily WTF

The Crossroads

I moved some things around on my calendar. 4:00 PM today is open. Please come to the executive floor.

-Leila

For a while I was stunned, staring at the email in front of me. I’d just told my boss I was quitting, refusing a promotion into my recently-deceased mentor Aggie’s shoes. Now, the new head of Human Resources wanted to see me.

Me? A Tech Support drone with one foot out the door? Well, she didn’t know that yet, did she?

Something in me feared where this might lead. But, Leila had stuck her neck out to rescue me from CEO Gibbs. She seemed like she cared about making things better. I decided to hear her out. Figured I owed her that much before I blew outta there for good in two weeks.

I had way too many hours to kill. Between whittling down my overstuffed inbox and resuming casework, it should’ve been easy to distract myself, but I couldn't focus on a single thing. I’d just done what had once seemed impossible. My brain wasn’t letting go of that any time soon.

Megan and Reynaldo also handed in their resignations. I got their messages confirming as much. We met up for lunch at a nearby restaurant and celebrated, but I was distracted. Amid the smiles and positive energy, the meeting with Leila was all I could think about. Should I mention it? I decided not to, not until I knew more.

I dreaded the afternoon slog now more than ever, but somehow, it slogged. When the clock’s hands finally crawled to 3:30, I threw on my coat and hat and darted out for one last smoke break. Then, it was time for C-Town.

Consumed with nervous energy, I shunned the elevator to race up the stairs floor by floor. Figured I’d burn off some stress, which could only help with whatever came next. Also figured I’d have a minute to recover in the vast executive lobby before finding my way to her office. Instead, I found Leila standing right there, every bit as polished as our surroundings. She faced me with surprise. “Hello.”

I tried to speak, laugh, something. Instead, I doubled over, coughing and gasping for air that felt all too thin up in nosebleed territory. While recovering, I couldn’t help but notice the gleaming tile beneath my feet, contrasting against my work shoes encrusted with sidewalk salt. Such details seldom crossed my mind, but the sort of people who worked up there lived and died for such details. Face flush, I cleared my throat one more time and righted myself, looking her way. “’Scuse me.”

“That was a long way up,” Leila remarked, gesturing behind herself. “I thought we could visit the observation deck. Would you like something to eat or drink first?”

Truth be told, I was already dying for another smoke. “No, that’s all right.”

“Follow me.”

She led the way through massive, quiet corridors to a small room with glass walls and ceiling. At this height, all one could see outside was a thick lead wall of fog. Leila strayed up to the far wall, a jewel against the void, and glanced back over her shoulder with chagrin. “I’m sorry, the view’s not very good today.”

“I dunno, I kinda like it.” Something about foggy weather had always intrigued me. With the normal world gone, it seemed like anything could happen.

She beckoned me closer with one hand. I strayed up next to her right side, staring out at the shrouded view.

“I understand you and Agatha Shaw were close,” Leila began quietly. “You have my deepest condolences.”

A two-ton anvil crashed onto my nerves. My fists clenched up at my sides. I worked so hard to hold back the flash-flood of grief that I couldn’t string words together. I only trusted myself to nod.

She glanced my way, hesitating. “Would it be better if we rescheduled?”

“I’m here,” I forced out. “Whatever you have to say, say it.”

She nodded. “First: while you were out of the office, I asked Francis Bronson to hand in his resignation.”

I drew a blank on the name, and blinked her way in confusion.

“The manager who nearly destroyed a printer with his hair dryer,” Leila explained, “after I’d just made a company-wide push for everyone to respect our office equipment.”

“Oh. Hothead!” My nickname for the guy. I’d worked that case a few weeks ago, but it felt more like years. Hothead worked in HR—at least, he had. After disarming him, I’d sent Leila an email, appealing for help against someone who clearly shouldn’t have been managing a supply cabinet, much less human beings. Well, she’d delivered. A warm note of satisfaction offered me a welcome lift out of grief. “Thanks. Really.”

Leila smiled. “We make a good team, I think. Which brings me to the other thing I wanted to discuss. Something new.”

My gaze fastened onto hers with a mix of intrigue and dread.

“You and I both know how badly this place needs to change. Let’s work together and actually fix things. I want to create a Change Management team and make you Team Lead.”

I was speechless, caught completely off-guard.

“The first thing we’d do is attack our company-wide leadership problem. Audits, surveys, hearings … eventually, a reorg. Along with simplifying the corporate structure, we’ll get rid of all the—Hothead, you called him? All the other Hotheads.”

“The biggest hothead is sitting at the top of the whole rotten pyramid,” I blurted. “He ain’t budging. He ain’t signing off on this, either!”

Leila was unfazed. “I think we could frame everything in a way that makes Mr. Gibbs like it. After all, we’re reducing payroll. We’re better positioning ourselves in a tough economic time. Worst-case, we could always use the three magic words: Google Did It.” She smirked.

I couldn’t help smirking back. Then I remembered what I’d done just a few hours earlier. “But I’m outta here. I quit! Put in my notice this morning!”

Leila nodded calmly. “Do you have a new position lined up somewhere else?”

“No. I'm going freelance with friends.”

“Friends who are leaving the company along with you?”

I nodded.

She paused for thought. “If you were to lead my Change Management team instead, you’d be able to recruit internally for your team. Whoever you think would be the most helpful. You’d set the agenda for whatever’s most important to address so that other good people don’t feel like they have to get away from here. All of this would mean a promotion to Director, with a salary and benefits to go with. And if you need more bereavement time, I could arrange an indefinite leave of absence until you feel ready to come back.”

The breath died in my throat. Had I suffered a stroke? I must’ve had a stroke. No, she really said it. She was on the level. I could change things. I could hire my friends to help me do it. A raise, full bennies, working with her every day?

Only a fool would refuse. And yet, my gut ached at the idea.

I stood there, frozen and mute, until I remembered something in my trench coat pocket: RD, the rubber duck I’d miraculously rescued from Aggie’s former office. I reached into my pocket and seized him in my fist.

RD? Aggie? I thought. Whoever’s listening. It all sounds amazing. I know she means it. But … it’s another trap, isn’t it? Staying in this joint for any reason means betraying myself. Betraying everything.

“Listen,” I finally said, “I’m flattered you even offered, but it ain’t right for me. Don’t give up on your idea! I’ve got friends here with ideas of their own for changing things. 32-hour work weeks. The end of free overtime. A union. I’ll send ’em your way. Offer them a spot on your team.”

Leila sighed. “A union would be an especially tough sell to Mr. Gibbs, but that really is a case where Google Did It. We might scare him so much with that idea that everything else would seem harmless in comparison.” She faced me with a sad smile. “A shame that we’re losing you. I was starting to learn some interesting things about printers.”

I’d miss her, too. And yet, I was feeling surprisingly great about my refusal.

“Make sure you file for unemployment,” she said. “We won’t stand in your way.”

I offered my hand. “Thanks for everything, Leila. Whenever it is they kick you outta here for good, come find me.”

She shook, sad smile persisting. “Maybe I will.”


I told Megan and Reynaldo about the new Change Management team. Made sure they knew the offer was on the table in case they preferred that over jumping ship. Both were quick to say no. Like me, they were too excited about our plans to stop now.

For the next couple of weeks, there was still plenty of work to be done: transferring my open tickets to other support reps and all that. But there was barely any time for it. Coworker after coworker stopped by my cube to express their surprise and wish me well in whatever came next.

“You’ll never be problem-free,” one of them advised me. “Go looking for the problems you want to have.”

I felt happier, freer, more determined than I had in ages. It was the conviction of knowing I’d stuck to my guns to do the right thing for myself.

Sanjay also jumped ship to join us. And there was one last surprise that came in the form of a phone call. The name on my work phone’s caller ID was DRACORA, P. So-called “Dracula!” Having a fairer opinion of her than most, I picked up without any sense of dread.

So-called “Dracula!” She hadn’t been so bad at all. Surprised, I picked up in a hurry.

“I’m so sad to hear you’re leaving!” she said. “What kind of freelance work are you doing?”

“All sorts of IT projects,” I replied. “Maybe some consulting on the side.”

“I have a friend who needs help setting up a website for her business. Is that something you could help her with?”

My eyes flew wide open in shock. “Sure!”

“I’ll put you in touch with one another.”

“That’d be swell. Thanks!”

We exchanged contact info. She promised to keep pointing friends our way whenever she could.


On my last day, I sent my personal contact information to my coworkers. I reminded them of Leila’s offer and urged them to keep me posted on their different causes. Then my friends and I walked out of a building that no longer had a hold over any of us.

It felt pretty damn swell.

Our accountant helped us incorporate RD IT Solutions. Only close friends knew it stood for “rubber duck.” The company covered medical and other relevant expenses for everyone. There was no hierarchy. Everyone had equal financial stakes and an equal say in company decisions.

After decades of being an expert at what I did, I was back at square one, learning the ropes. So much of what we had to learn for our business could only be learned through failure. Still, it felt rewarding to challenge my brain in new ways. The new gig let me wear lots of hats, from tech support to coding to business admin.

With no more regular paychecks, we had to tighten down our finances to what was critically important. We worked remotely at whatever times worked best for us, with the occasional meet-up at a public place or someone’s home. We all knew that any one of us having some kind of trouble could count on the rest of the group to help out as best as they could.

Megan quit smoking again. I cut way back myself. Wasn’t trying to, I just haven’t felt the need as much. Also stopped having those nightmares. It no longer feels like I’m living just for time off and weekends. I don’t spend my Sunday nights dreading Monday.


Dracula really did introduce us to our first client. It’s crazy what the universe puts out there when you go looking for it.

We met up remotely for our first client meeting to discuss requirements and expectations. When the topic of deliverables came up, our client scrunched her nose and interrupted Megan mid-sentence. “I don’t trust email! I’d rather you fax me the files.”

We were building a website for her.

“You mean, the source files?” Megan soldiered on bravely.

“Just fax me the codes,” the client said. “My nephew can re-type them into the Internet.”

She provided a fax number, fully expecting us to print out several hundred lines of code to send over. After deploying our first stab at a website that met her requirements, we did just that, mostly out of curiosity.

A few days later, she called us in a huff, saying her website looked like random letters. Her nephew had typed the code into Facebook.


FIN

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

by Ellis Morning at August 10, 2026 06:30 AM

XKCD

August 07, 2026

ISO C++

A Coalescing Event Queue for High-Frequency Systems -- Ajay Pandey

1.pngTraditional queues collect every event. Ajay Pandey shows how a coalescing queue can avoid redundant updates while keeping relevant state.

A Coalescing Event Queue for High-Frequency Systems

by Ajay Pandey

From the article:

High-frequency event-driven systems often ingest more updates than downstream components can usefully process. A conventional FIFO queue preserves every event, but that can be the wrong abstraction when the consumer ultimately needs a current view of state rather than a complete history of every intermediate transition. This article describes a coalescing event queue: a design pattern that buffers events over short, bounded time windows and applies explicit merge policies to reduce redundant updates while preserving the most relevant state. The design uses a multi-producer, single-consumer concurrency model, key-based coalescing, policy-driven merge rules, and a decoupled dispatch layer. A C++ sketch illustrates how the queue can be implemented with clear ownership, bounded synchronization, and extensible merge semantics.

The problem with treating every event equally

Many systems are built around the assumption that every event should be queued, preserved, and processed in arrival order. That is a reasonable default for audit trails, ledgers, command streams, transactional pipelines, and any workflow where the complete sequence is semantically important.

It is not always the right default.

by Blog Staff at August 07, 2026 08:48 PM

The Daily WTF

Error'd: Time Wounds All Heels

Looked to the past for some time-traveling entries to round out a themed post. They're 25% fresh.

Robert apparently got a notification of a planned past delivery. It could be just a case of two systems that don't report different time zones, but even so, that's a wtf. Says he: "I just received an email from OnePlus this morning letting me know they have updated the planned delivery date for my order to Yesterday. I guess the delivery driver is going to time travel to get there on time since it still hasn't arrived. "

10c678e3b0bc4ec79761a9998cc687bb

Kinkster Ypsilon Omega was really turned on by a time-traveling hottie who posted a photo an hour before joining. "(Heavily redacted screenshot.) Either Fetlife (a kink community website) is very welcoming to time travelers, or allows new members to upload their profile picture. Because time handling code surely never fails..."

17a1e640495b493a9e34c463749ade73

ERIC P. shared a photo from 2023. "My 2008 Ford has suddenly time-warped 1024 weeks into the past. GPS date roll-over bug. No updated firmware available. No way to set the calendar manually. No way to turn off the date display."

a8a33a11c9624ab5af5e7272a838237e

Marc Würth "... just added a new RSS feed to my Netvibes dashboard (great tool otherwise, by the way). While it was still fetching the feed, it showed these peculiar crawling stats. Once fully loaded, it showed sane info, though." I'm curious about the specificity of 261 years.

d2c88222c5554be2bcd6c051f19072ae

Quite recently, an anonymous slightly flexed "Not only did I receive two parcels prior to the Roman conquest of Britain, but the date calculation for the combined notification has then failed and returned the Unix epoch." For those who missed the flex, dig Wikipedia: "Wardian London is considered to be the most expensive residential development in East London." I guess they can afford professional time travelers.

fac2c471b782468c8c2e3a1afdb808f4

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

by Lyle Seaman at August 07, 2026 06:30 AM

XKCD

August 06, 2026

ISO C++

CppCon 2026 Towards a Complete Contract-Assertion Facility for C++ -- Timur Doumler

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

Towards a Complete Contract-Assertion Facility for C++

Monday, September 14, 2026 14:00 - 15:00 MDT

by Timur Doumler

Summary of the talk:

C++26 introduces contract assertions: language-level constructs for expressing expectations about program correctness, optionally checking them at runtime, and configuring how violations are handled. However, what ships in C++26 is intentionally minimal — not the final destination, but a carefully designed foundation for a much more capable facility.

In this talk, we begin with a brief overview of contract assertions as they exist in C++26, including the three kinds of assertions ( pre , post , and contract_assert ), the four evaluation semantics ( ignore , observe , enforce , and quick-enforce ), and the user-replaceable contract-violation handler. The focus of the talk, however, is the next stage of evolution already underway.

We will explore the major extensions currently planned for C++29 and beyond, and the problems they are intended to address, and how they build upon the extensibility intentionally designed into the C++26 facility. Many of the concerns raised during standardisation — particularly around scalability, configurability, and expressiveness — are already being addressed by these extensions. We will discuss contract assertions on virtual functions; grouping contract assertions and configuring evaluation semantics by group; constraining evaluation semantics (for example, assertions that must always or never be enforced); postconditions that refer to earlier program state; user-defined diagnostic messages; and finally, compiler-generated, implicit contract assertions guarding against core-language undefined behavior. We then look even further ahead at more ambitious ideas still in earlier stages of exploration: class invariants, contracts on function pointers, and procedural interfaces.

Rather than just listing the proposed extensions, we will examine the design considerations behind them and show how the new functionality fits into the broader model of contract assertions in C++. What does it mean for contracts to participate in virtual dispatch? When can contract assertions support optimisation? How can evaluation semantics remain both predictable and configurable across large codebases? Understanding these questions is essential to understanding where contract assertions in C++ are heading next.

This talk is intended for anyone interested not only in how contract assertions work in C++, but also in the principles shaping their future evolution — and what a complete contract facility for C++ might ultimately look like.

by Blog Staff at August 06, 2026 06:31 PM

The Daily WTF

A More Civilized Age

Greta (previously) sends us more updates from her "Ancient Development Environment".

An important task an IDE must do is report build errors to its users. Arguably, that's one of the most important parts. I wouldn't know, I insist on building from the CLI all the time, because IDEs confuse and frighten me. I recognize I'm the weird one here, who is more comfortable in GDB than in a GUI debugger, but this isn't about me, it's about the IDE Greta is using.

It needs to display an error. Why does it need to display an error? Well, Greta hasn't figured that out yet. The error I'm about to show you doesn't really explain what happened or why or give any hint as to what needs to be done to fix it. To make matters more confusing, it doesn't happen consistently, so simply re-running the build could potentially fix it.

None of that is why we're here, though. What makes this a WTF is how the error is displayed:

An error box in a very Win3.1 style. It displays the error as a tree view, and the error is actually an XHTML document. But it's not rendering as XHTML, it's just raw HTML code, shown as a tree, like a really cruddy DOM inspector

Greta shares her bullet points about what she hates about this:

  • It's a popup that happens arbitrarily during build, under unknown conditions
  • It says nothing about what went wrong, or indeed if anything went wrong
  • It's in a non-user-legible XHTML format. It shows the markup of this XHTML rather than it being rendered.
  • It arguably shows the XHTML markup in the worst way possible: in a tree view (?!) with one row per source line
  • The markup isn't even well-formed. I'll let you count the reasons why.
  • The control used is from some sort of legacy windowing toolkit that doesn't support text anti-aliasing.
  • The first button on the upper-left, "Get latest C++ Builder Direct headlines from the Internet", does nothing.

I'd honestly forgotten about the era when the Internet was still kinda novel so every application had a "push a button and go to our web page, and this somehow definitely won't just break when we change our URL structure in the future."

Greta adds:

For all of the hatred I harbour for this, the second button ("Information about C++ Builder Direct") brings up the following powerful dose of 90s nostalgia, so I can't stay mad:

An about box, with a very 16-color gif globe, wrapped in a cable terminated with an RJ45 connector, along with some copy about how C++ Builder will reach out to the Internet and bring the latest news TO YOU. Aren't you excited?
[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

by Remy Porter at August 06, 2026 06:30 AM

August 05, 2026

ISO C++

C++ Reflection: a Universal Printer -- Lieven de Cock

logo.pngC++26 introduced reflection. Lieven de Cock demonstrates how to print information about class members using this new feature.

C++ Reflection: a Universal Printer

by Lieven de Cock

From the article:

The challenge of this article is to write a universal printer/formatter, so that we can format (nearly) any type we have. By that we mean print out the values (and names) of all its members, including the members of base classes.

Let’s get started.

The Lift operator

The first thing we need to do is move from the code domain to the reflection domain, and that is done by applying the ‘lift operator’ (^^) to a specific type.

Say we have a type Coordinate:

  struct Coordinate
  {
    int x{10};
    int y{20]:
    int z{30};
  };

Let’s reflect on it with ^^Coordinate. This gives us an object of type std::meta::info, and this contains a lot of information we can inspect by calling several inspection/reflection methods.

by Blog Staff at August 05, 2026 08:46 PM

CppCon 2026 Back to Basics: Move Semantics -- Ruslan Arutyunyan

Registration is now open for CppCon 2026! The conference starts on September 12 and will be held in person in Aurora, CO. To whet your appetite for this year’s conference, we’re posting some upcoming talks that you will be able to attend this year. Here’s another CppCon future talk we hope you will enjoy – and register today for CppCon 2026!

Back to Basics: Move Semantics

Monday, September 14, 2026 11:00 - 12:00 MDT

by Ruslan Arutyunyan

Summary of the talk:

Move semantics and perfect forwarding, introduced in C++11, are quite impactful features that still remain a source of confusion even for some experienced developers. This talk builds understanding from the ground up: what problem move semantics solves, how rvalue references enable it, and why the rules work the way they do.

We start with the cost of unnecessary copies and how move constructors and move assignment operators let us transfer resources instead of duplicating them. We then look at how std::move doesn't actually move anything — and what it really does. From there we tackle the forwarding problem: why writing a single function that preserves the value category of its arguments is necessary, how forwarding references (also known as "universal reference" in the past) solve it, and what std::forward does under the hood.

Along the way we cover the practical details that trip people up: reference collapsing rules, the interaction between overload resolution and reference binding, when the compiler generates move operations and when it doesn't, and the cases where std::move can actually pessimize your code. We also discuss trade-offs in parameter passing — by value, by const reference, or by forwarding reference — so attendees should have a clearer model for making these decisions in their own code.

At the end we will look into std::forward_like and explore how it is different from std::forward .

No prior knowledge of rvalue references is assumed. Familiarity with copy constructors, destructors, and basic templates is helpful.

by Blog Staff at August 05, 2026 03:15 PM

The Daily WTF

CodeSOD: Connection State

Frederick A sends us a bit of null checking code, and offers us a better solution.

class ConferenceService
{
	/// <summary>
	/// Checks if conference is active
	/// </summary>
	public bool IsCalling()
	{
		try
		{
			return m_ConnectionService.Core.State.IsWebRTCConnected;
		}
		catch
		{
			return false;
		}
	}
}

This is for a web conferencing tool, which uses WebRTC to set up connections between clients in the chat. This function checks if the chat is active by checking a IsWebRTCConnected flag. But as you can see in this code, that flag is on a long chain of objects, some of which may not exist when this function is called. Thus, we wrap the whole thing up in a try/catch. If anything throws an exception, we know we can just return false. It's probably fine.

The obvious and easy fix, which Frederick proposes, is to use the C# coalescing operator: ?. m_ConnectionService?.Core?.State?.IsWebRTCConnected ?? false would solve this problem just fine.

That said, I wouldn't say that's a true fix. We're talking about a state machine here, though admittedly with two states under discussion (connected/disconnected), though there are probably more not being checked here. This information should be managed via a state machine, not via boolean flags stuffed deep in an object chain. The fix isn't a WTF, but it definitely hints at a better way to manage all of this. Now, my solution likely requires a lot more modification and code changes than what we have here, so I'm not suggesting anyone go off and rewrite this from scratch just to have a cleaner way of managing state. But folks definitely should think more carefully about how they manage state.

[Advertisement] Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.

by Remy Porter at August 05, 2026 06:30 AM

XKCD

August 04, 2026

The Daily WTF

CodeSOD: Always Take the Option

Frequent submitter Capybara James sends us this simple snippet, which highlights that even when you have the lovely convenience of Optional types, you can use them wrong.

if (StringUtils.hasLength(dto.getAssetModelUUID())
		// Other conditions
		) {
	return Optional.ofNullable(dto);
}

We access the getAssetModelUUID member of dto, and if it's a non-empty string, we can then return a nullable of this thing that's definitely not null in the first place.

Okay, in the scheme of things, that's not that bad. All we're really doing is just not using the syntactic sugar that automatically boxes your dto into a nullable type. On it's own, it's not bad, just ugly. But like all things, it doesn't exist on its own. It exists inside of a giant pile of code where this pattern is used all the time. Even functions which don't return nullable types box (and unbox) the type. Optional is scattered through the code like a magic ward against null reference exceptions.

Does it help? No, not really, the code is buggy and error prone. Will it ever get fixed? Probably not in this lifetime.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

by Remy Porter at August 04, 2026 06:30 AM

August 03, 2026

ISO C++

Avoiding having to calculate the gcd when doing cycle decomposition -- Raymond Chen

RaymondChen_5in-150x150.jpgLast time, we looked at how clang’s libcxx implementation of std::rotate uses cycle decomposition to minimize the number of swaps. Doing so requires calculating the greatest common divisor, but I noted that the OpenJDK implementation of the java standard library uses a trick to avoid doing the gcd calculation.

Rotation revisited: Avoiding having to calculate the gcd when doing cycle decomposition

by Raymond Chen

From the article:

The trick is realizing that the total number of elements is equal to the sum of the lengths of each of its cycles, and each of the initial elements belongs to a different cycle. Therefore, we can just keep rotating elements until the number of elements rotated is equal to the total. We don’t have to precalculate the number of cycles; we just let the counter tell us when we’re done.

auto a = std::distance(first, mid); // number of "A" elements
auto n = std::distance(first, last); // total elements
auto count = 0;
auto k = 0;

while (count < n) {
    // Rotate the elements in the cycle starting at k
    auto save = std::move(first[k]);
    auto i, next = k;
    while (i = next, next = (i + a) % n, next != k) {
        first[i] = std::move(first[next]);
        ++count;
    }
    first[i] = std::move(save);
    ++count;
}

by Blog Staff at August 03, 2026 08:42 PM

The Daily WTF

Lose Some Padding

Flat-file style databases were designed to fit the constraints of the systems they were running on. You specify your schema in terms of "how many characters in a file we use to store this data", meaning something like this: JOHN    SMITH    12343rd    StAnytown PA12345 is read in my knowing that the first name field is 8 characters wide, the last name field is 8 characters wide, the street number is 4 digits, and so on.

It's also a terrible schema, and woe to anyone with a long name. But many a mainframe had a similar schema.

Now, let's think about maintenance here. What happens when we also want to store a middle initial? We've created for ourselves a problem. Somehow, I have to insert a character into every row, which basically means making a new table with a new schema, copying every record out of it and updating it to use the new schema. I can't just ALTER TABLE like an RDBMS. And worse, every piece of software that touches the table also needs to be updated. On a large legacy system, a simple task like "add a field to our database" could take weeks of developer time, and depending on the software, be a high risk operation.

Which is why the smart developer, when working with flat files, includes padding. Maybe my schema for an address record looks more like this: JOHN    SMITH    12343rd     StAnytown PA12345                . That's 16 characters of padding at the end of the file. Now somebody says that I need to store a middle initial, I can just shrink the padding by one and add a middle initial field, like so: JOHN    SMITH    12343rd     StAnytown PA12345Q               

Is this elegant? No. But it works. I haven't changed the length of the row at all, so I don't need to move data around. Software modules only need to be updated if they care about what's in the middle initial field; if they're out of date, they just think there's a "Q" in the padding, and don't care.

In real-world applications, instead of putting all the padding at the end, you'd usually put the padding in a few spots in the middle of the table. Any time you need a new column, you just steal a few characters from padding. Sure, someday you'll run out of padding, or at least out of padding blocks big enough for your new field, and then you'll have to do the hard work of shuffling data around. But in practice, you can get very far without that happening.

Which brings us to Brenda's adventure. Her team supports an IBM mainframe storing data in VSAM flat files. In other words, they've been doing the sort of thing I just talked about for many, many years.

Of course, in the modern era, you can't just leave your data sitting in an mainframe. Even if the mainframe is the source of truth, you want to be able to report on it and connect it with your other data systems. You need to, somehow, get the data into a modern RDBMS.

So the company hired a bunch of developers to write an extract-transform-load process, which pulls the data out of the mainframe. The mainframe team handed them a "copybook" for the flat file, which described the structure, and the ETL devs went to work.

And maybe those ETL devs didn't understand the importance of padding. Maybe they just missed the padding. Whatever it was, there were several places where the data was structured like SOME_USEFUL_FIELD PADDING PADDING PADDING SOME_OTHER_FIELD, and they opted to split it like so: SOME_USEFUL_FIELD PADDING PAD, DING PADDING SOME_OTHER_FIELD.

When they released this process, it was fine. The padding characters got stripped before displaying, so the users never saw them. They were stored in the database, though, so when someone tried to reconstruct the data in a way that was compatible with the flat files, you could just concatenate the columns together and get a valid result.

It was fine- until it wasn't. The ETL devs, bless their hearts, only tested against the production mainframe. And why not, they were doing read only operations, what's the harm? Had they tested against the development mainframe, they would have seen new features in flight, features which consumed some of that padding, and realized that they should have paid closer attention to the copybook.

But instead, the test cases all passed. The software was, as far as the project managers and ETL developers could tell, working perfectly. So it was accepted, released to production, and running for a few weeks before the mainframe released its features. Those features then ruined all the beautiful reports with extraneous data.

And since the ETL devs were on contract, any request to have them rework it under the original contract was met with a stern "Works as designed". Instead of paying the contractors to come back and rework the system, the mainframe devs instead were tasked with finding different padding fields they could use, padding fields which wouldn't end up ruining any reports management liked to see.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

by Remy Porter at August 03, 2026 06:30 AM

XKCD

August 02, 2026

ISO C++

BeCPP Symposium 2026 - Phil Nash - Contemporary C++ Testing

BeCPP Symposium 2026 (organized by BeCPP): Now on YouTube!

Phil Nash - Contemporary C++ Testing

Abstract:

It's been 15 years since Catch claimed to be a "Modern C++ Testing framework". C++ has been through some game changing stages of evolution in that time. What would a test framework built for the C++ of today look like?

About the Speaker:

Phil is the original author of the C++ test framework, Catch2 and other open source libraries.
A Senior Software Engineer at Bloomberg he has had a career that spans finance, mobile and software security, with a diversion into Developer Advocacy at JetBrains and Sonar.
He's also a member of the ISO C++ standards committee, organiser of C++ London and ACCU on Sea (the merging of the ACCU conference with C++ on Sea), as well as former co-host and producer of CppCast, cpp.chat and No Diagnostic Required.

 

by Marc Gregoire at August 02, 2026 01:08 PM

July 31, 2026

The Daily WTF

Error'd: I Believe In Lingonberries

I've never been a huge fan of their furniture but I will happily demolish a plate of meatballs.

Jan agrees "My loyalty to this Swedish megastore is immeasurable."

1aecb9456a1643de971951645d5f70fe

"Choosing Concert Seats is Surprisingly Hard" for jeffphi who explains "While I have mixed feelings about indulging in nostalgia tours, I was curious to see seating options for this Rick Springfield concert. Turns out I *still* have questions!"

2f0e93e3ff154b5692d6d25fcb3a699b

"Would you like to undo this unspecified problem?" richard H. rants "This came out of nowhere while composing an email. (I think I had just hit 'enter' to move to the next line.) Does anyone at Microsoft read these error dialogs before they ship it? Anyone? Is anyone at Microsoft forced to endure their own software?"

6485ee06e6a047d59d5a014e5901d8ba

An anonymous fan of extinct charismatic megafauna complains "This is %{insult}"

e684ff08ade843449f464d69e3f0ef0d

Finally, and most seriously, merely pseudonymous WeaponizedFun has just highlighted for us that a true secret is something only one person knows. "Apparently, when OnSolve says "PROTECT YOUR USERNAME - NEVER give your username to anyone," this includes them not telling me what it is." See, if they told you, it wouldn't be a secret anymore.

46997513448d450189e4881a58d96af3

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!

by Lyle Seaman at July 31, 2026 06:30 AM

XKCD