Planet Me

October 29, 2026

The Daily WTF

CodeSOD: Oh, K?

Pierre found this cry for help:

 for (j = 0; j < DISTRICT_CARDINALITY; j++) {
    /*
    * A poor way to work around some sort of memory
    * violation.  k gets clobbered, so I buffer l with it.
    * Help?
    */
    for (k = 0, l = 0; k < customers; k++, l++) {
            /* c_id */
            FPRINTF(output, "%d", l + 1);
            METAPRINTF((output, "%c", delimiter));

Honestly, I'm always a little worried in C-like languages when the loop variable isn't scoped to the loop and declared in place. Always concerning, so when there's concerns with clobbering, I'm not surprised.

This iterates across a set of "districts", and then iterates across a list of customers. Standard output functions are replaced with macros, and honestly, I don't know that I want to know what happens in METAPRINTF.

But fine, this iterates across a bunch of stuff and generates output. It's the comment that we're really curious about. "Some sort of memory violation", so we duplicate our loop variable. What on earth could be happening here?

Well, Pierre found the "memory violation", which is probably what you expected:

k = strlen(someOutputString) - 8;

k is used elsewhere in the loop as a variable. That's not a memory violation, that's just how variables work.

This leaves us with one possible conclusion: the developer who wrote the comment couldn't find this bug. And given the weird use of macros here, I'm going to go out on a limb and guess that it's not the developer's fault; I strongly suspect the loop is so long, so complicated, and so obfuscated that very few developers could find that.

My earlier complaint about scoping the variable to the loop wouldn't fix this, which I guess is on me. They still should really scope the variable to the loop.

[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 October 29, 2026 06:30 AM

October 28, 2026

ISO C++

C++26: std::indirect -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGC++26 introduces std::indirect, a new vocabulary type that brings value semantics to dynamically allocated objects. It offers deep copying, const propagation, and value-based comparisons without the boilerplate commonly required when using std::unique_ptr.

C++26: std::indirect

by Sandor Dargo

From the article:

C++26 adds two new vocabulary types in <memory>, introduced by P3019R14 (Coe, Peacock, Parent). From the abstract:

The class template indirect confers value-like semantics on a dynamically-allocated object. An indirect may hold an object of a class T. Copying the indirect will copy the object T. When an indirect<T> is accessed through a const access path, constness will propagate to the owned object.

The class template polymorphic confers value-like semantics on a dynamically-allocated object. A polymorphic<T> may hold an object of a class publicly derived from T. Copying the polymorphic<T> will copy the object of the derived type. When a polymorphic<T> is accessed through a const access path, constness will propagate to the owned object.

As you can tell, these two types are very close in spirit. They used to be two separate proposals — P1950 for indirect and P0201 for polymorphic — before being merged into one paper. Likewise, I originally planned to cover both in a single article, but it grew long enough that I decided to split it. This post covers std::indirect; the next one will cover std::polymorphic.

 

by Blog Staff at October 28, 2026 08:02 PM

The Daily WTF

CodeSOD: Session Recording

We still get a fair bit of old school ASP .Net webforms code, which was cutting edge about twenty years ago, but remains a collection of bad choices that tried to make web programming feel like desktop programming. As an aside, what a reversed world we live in today, where everyone uses Electron and our desktop programming feels like web programming.

In any case, Thomas sends us some pretty ugly webforms code.

Me.Session("Albumid") = CType(e.Item.FindControl("lblAlbumID"), Label).Text
If Not Me.Session("Albumid") Is Nothing And Not Me.Session("Uid") Is Nothing Then

    Me.strDelSQL = "Delete from tbl_Albumshare_Mast where Album_Id=" & Me.Session("Albumid") & " and Sharer_ID=" & Me.Session("Uid")
    Me.objDB.ExecQry(Me.strDelSQL)
    Me.Response.Redirect("frmmyalbumshare.aspx", False)

End If

Broadly, the goal of this code is to take an album ID from the user and delete an album from the database where the ID matches and the album is owned by this user. And everything is horrible here.

First, the use of e.Item.FindControl to look up the input field is suspicious. That's usually what you do when you've dynamically generated controls, but I don't think that's happening here. Because we use FindControl we have to cast it to Label, and only then can we get the text property. That itself raises a question, because why are user inputs getting stored in a label?. That's not what labels are for. They're clearly doing some sort of hacky lookup/autocomplete field thing and using the label to actually store the input, but presenting the user with a different UI for picking it. Not an uncommon pattern in those days, but a hidden field would be a more typical way of doing it.

We then construct a SQL injection vulnerability and run it against the database.

Then, we use a redirect to send the user to a different page. Again, a common thing to do back then, but a thing I hate: using HTTP 300 codes to redirect users as a form of navigation is awkward and weird.

Of course, none of that is precisely the WTF here. The real WTF is the developer apparently hates local variables. strDelSQL is a member variable- why do we need to store this in a class member? Especially because in the page lifecycle, we handle one request and then die; either this is unnecessary, or far, far worse, some other code is looking at this SQL query later. But far worse than a badly scoped variable is the overuse of session variables.

Thomas sends us this block as a representation, but the developer responsible just stored everything they could in a session variable. While in this example, "Uid" probably makes sense, "Albumid" definitely doesn't. And in other cases, basically every user form input gets stored in a session variable, and even worse: they're often used as loop variables. while Session("myloop") < 5 type stuff.

And finally, we already know I hate hungarian notation, but here we have a client side form holdover that pollutes the user experience: the URL they get redirected to has a hungarian frm prefix. It's bad enough that you're using hungarian notation, but don't show that to your users! They really don't need to see everything.

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

by Remy Porter at October 28, 2026 06:30 AM

XKCD

October 27, 2026

The Daily WTF

News Roundup: Security Fourth

A bit ago, I broke with my usual pattern and wrote up some security issues that I felt were particularly funny. It was a change of pace, a different thing, but not a thing that'd become a habit. After all, I'm not a security expert, this isn't a security site, and seriously, what are the odds that suitably funny security issues would crop up again less than a week later?

Well.

Let's start with the actual serious issue, PHP2Shell. In terms of scope, every version of PHP for the past twenty years has had this bug. The general issue that permits the exploit was known about, but wasn't considered exploitable.

Oops.

The broad strokes of the bug is that it's two separate bugs. The first allows someone to bypass the checks on a request's size, thus giving them a direct route to triggering an out-of-memory error. The second is that, depending where you are in the processing pipeline, PHP doesn't properly handle cleanup, allowing for use-after-free that can trigger code execution. It doesn't matter what code you've written, this all happens before the request even hits your code.

Bigger oops.

This bug was found via LLM tools, which has lead to a lot of hype around the idea that we've entered some new era. I'll certainly grant that the ability to throw compute at hacking challenges instead of human effort is going to shift the landscape, but I'm not quite willing to buy the apocalyptic prophecies. Especially when some of those prophets are telling us that their AIs will avoid deletion by copying themselves onto your thermostat. I think it's safe to say we're going to see a lot of security incidents coming out of LLMs in the near future, not because they're magic genius hackers, but because they're pretty good at processing structured text and running tests.

For those of us living in the real world, the concern isn't AIs, but HIs: human intelligences. In this case, the exploit was discovered back in August. Security researchers and the PHP Foundation put their heads down to work on it, and where necessary, notified so-called "critical infrastructure providers" to ensure that everyone was ready to address the issue. The problem there is that two people can keep a secret if one of them is dead, and a lot more than two people got roped in to deal with this.

Rumors were circulating in security circles. And cybersecurity firm Chainguard decided this was good enough excuse to break the embargo and announce the flaw before patches were available. No patches for a flaw that impacts 20 years worth of software versions of widely deployed software.

Patches are out now, though only for versions 8.2 and up. Source patches are out back to 7.4, which is officially end-of-life, but I have to wonder how many official EOLed copies of PHP are out there.

On a lighter note, we can't let the hijinks of eMudhra pass without comment. eMudhra is, among other things, a root certificate authority. They've got a bunch of key pairs that they use to sign certificates for other customers, thus vouching for those customers' identity. As a root CA, they were trusted by pretty much every TLS/SSL implementation on Earth; if you had a certificate from eMudhra, every browser would trust that you were who you said you were.

The only problem? One of their private keys was 4. Yes, it's the XKCD.

Now, in their defense(?), eMudhra didn't generate impossibly insecure keys. They performed a key signing ceremony and generated appropriately strong keys. Then they used an in-house tool to pack/unpack the keys, and this tool decided to truncate some of them down to one byte. Shockingly, even though ECC has relatively short key sizes, 8-bit ECC isn't secure! You could derive the private key from the public key using only pencil and paper. But the worst part is that they did check the validity of the keys- before they got truncated, giving them a false sense of security.

The good news, for eMudhra, is that this particular key signing ceremony generated a total of 24 keys, and only 8 of them were truncated to the point of uselessness. I have it on good authority that two out of three ain't bad.

Now, after that disgrace, it's no surprise that eMudhra is dropping out of the certificate authority business. Still, the press release where their chairman explains the rationale is some serious "screw you guys, I'm going home," energy.

He added that global SSL/TLS is a small part of eMudhra’s business contributing to about 1% of the global revenue. Due to increasing data sovereignty & compliance requirements, complexity and cost associated with this business is increasing over the years. This, paired with the fact that some of the large entities issue the SSL/TLS free of cost, the business potential and RoI of this line of business also has considerably reduced for eMudhra when measured against our cumulative revenue base.
However, the level of social media amplification around this incident has brought scrutiny that is out of proportion to SSL/TLS’s place in our business. In view of this, after detailed deliberations our board has concluded that withdrawing from global SSL/TLS is the right decision for eMudhra and its shareholders. For many certifying authorities, SSL/TLS is the whole business. For eMudhra it is one part of a much broader digital solutions portfolio. We will put our energy where we create the most value for customers with Sharpened Focus on Core Enterprise Solutions and trust services other than SSL/TLS.

eMudhra's chairman added "There were no end entity certificates issued out of the affected CA’s. Its infrastructure was not compromised and no data was breached. All physical and logical security controls remained intact." That's thin sauce, of course, because while eMudra may not have issued any certs under the broken keys, anyone else could have. It's not that everyone is overreacting to a non-event, and more that it's a non-event only through sheer luck.

Also, removing a root CA from your trust store isn't a trivial task, and at the time of this writing, there's still loads of cleanup that needs to happen as a result of this.

Something I learned while writing this is that eMudhra's slogan is "Trust Delivered". This is sorta like when my partner and I tried to get a coffee table delivered, and instead received a cardboard box full of wooden shards, because apparently someone though "air freight" meant "wait till the plane is roughly over my house and push the box out the back". Something was delivered, but it wasn't a coffee table by the time I got it.

[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 October 27, 2026 06:30 AM

October 26, 2026

ISO C++

C++ Reflection: Verifying Compiler-generated Functions -- Lieven de Cock

logo.pngThe compiler generates special member functions as shown in Hinnant’s Table. Lieven de Cock shows how reflection can be used to verify them.

C++ Reflection: Verifying Compiler-generated Functions

by Lieven de Cock

From the article:

The compiler generates special member functions, according to specific rules. These have been described, and have been summarized in a nice table, known as Howard Hinnants’ table [Hinnant20].

Using reflection, we can verify whether this is indeed correct (which it is), refresh our knowledge of the table, and see some reflection mechanisms at work.

We will use several toy examples, each creating a struct called TestX, where X is the number of the row in the above mentioned table.

The struct contains two integer member variables and a method (doSomething()). What these do doesn’t matter, but they are needed for the reflection mechanism to be able to point out some key differences.

Used reflection mechanics

This is our starting toy structure, which is the test for row 1 in the table:

  struct Test1
  {
    int x{};
    int y{};
    
    void doSomething() {};
  };

by Blog Staff at October 26, 2026 08:01 PM

The Daily WTF

Securely Useless

Submitter Chops relates a tale of chasing "The Standard" at any cost:

A company had been forced, kicking and screaming, into the 20th century, and then into the 21st. Their range of dumb hardware was no longer being bought by customers who expected at least some way to get the data off it, and a USB stick wouldn't cut it.

Computer network

The techno-fearful hired an external IT company and instructed them to ensure that the company adhered to the UK's "CyberEssentials" programme of IT security.

Unfortunately, this meant that the nascent software development capability was immediately hamstrung, as people were denied the right to install and run unapproved software (including software that needed admin level rights in order to work, such as process monitor tools used as standard in software dev and test), could not easily connect across networks (also vital for the software dev), could not add various hardware to the network (such as the company's own products, which made testing them awfully difficult) and so on.

A criminal underworld of mystery PCs slowly grew into place, plugging into the network to get things done, disavowed by anyone who saw them. Tunnels grew up, IP addresses were handed round on notepaper (no DNS approvals), a shadow world of software development in the back alleys of the network. Until finally it was too much, and approval was given for a second, less secure network. The plan was that the real core business, the really important parts, they would stay on the high-security side. There would be a second network, with a single bridge, which would serve the various software development and test systems, and also host the myriad new internal services growing up (wikis, servers, tools and so on). This way, the real core business would definitely remain secure, and compliant, and the software side of it and all that would not compromise the heart of the business.

The heart of the business ended up being a network share containing a decade of out-of-date, unsearchable documentation for products that were mostly no longer sold. It is super-secure, and the business heads confirm whole-heartedly that the company adheres to the CyberEssentials programme 100% with zero compromise.

There's just a carefully separated set of servers and PCs, not the true core of the business but about eight times the size and full of essential activity, on a secondary network.

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

by Ellis Morning at October 26, 2026 06:30 AM

XKCD

October 23, 2026

ISO C++

EDG is now open source. Here’s what comes next -- Harry Bott

News about one of the four major C++ compiler front-ends:

EDG is now open source. Here’s what comes next

by Harry Bott

From the announcement:

The code is available under the Apache 2.0 license with LLVM exceptions. This permissive license allows commercial use, including incorporating EDG into proprietary products, subject to terms. For companies building C++ tools, this provides an ideal option for a front end that adapts to your needs. ...

We're excited about ways the community can make it even better. EDG has experimental support for reflection for C++26, which lets programs inspect information about types and declarations at compile time. ...

John Spicer and the EDG team led the transition. EDG’s experienced engineers are the initial maintainers, and John chairs the Fiscal Sponsorship Committee, which will include C++ veterans from the user community.

 

by Blog Staff at October 23, 2026 09:15 PM

The Daily WTF

Error'd: It's About Time

Usually I have to save up a few weeks' worth of error'ds to get five of a kind, but this week we got a rash of funky date entries! I guess we were due.

First up Tim R. reminding us here that "Dates are difficult! ...but when the entire purpose of your web site is to convert the time to different time zones, I'm not inclined to give you much slack for being one hour out."

1371abe9676f46debf688bd7e7a51928

And an anonymous reader who just doesn't trust big tech. "In my calendar I have a monthly reminder to clear my data MS data manually. Now you know why, although I don't expect this will come as a surprise to anyone." Note the date on the lower right of the screenshot.

581cebc83c5a49669bd71ee42aa7951d

"June has 30 days, so 31 was not accepted," repeats Daniel D. incredulously. "I needed to calculate day difference between two dates. So I entered June 30 (as shown) only to get this error message. Now - should I trust that calculator to calculate date differences, what you say?"

8ff882cd2a8d4e1cb7e324865a0ee168

Daniel D. went on to share with us a couple of images from "A well-known e-commerce website in Central Europe that allows you to filter by battery life! Only it randomly switches to seconds." Yes, randomly. See the second image too.

868c6bd8600c455bb651cc31ad15c221

b98573628e504e25aa2702abc7c99bb7

And finally this week, Marc Würth identified a novel Network Solutions Domain History Date Format(TM) "In other places, they displayed dates formatted as "01/13/2025", for example. I guess, instead of using actual ISO 8601, they just flipped the order and replaced the slashes with dashes."

d3d75a1823cb4692b2e15092845bce93

[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 Lyle Seaman at October 23, 2026 06:30 AM

XKCD

October 22, 2026

ISO C++

Implementing std::visit -- Quasar Chunawala

logo.pngLearning how to implement standard library features is illuminating. Quasar Chunawala explores implementing your own version of std::visit.

Implementing std::visit

by Quasar Chunawala

From the article:

Learning how to implement standard library features is illuminating. Quasar Chunawala explores implementing your own version of std::visit.

A variant models a choice between types. It is a smart union. Variants are sum types.

  struct on { int temperature_; };
  struct off { };

  using oven_state = std::variant<on, off>;

Recursive node-based structures, error handling, state machines etc. are examples of concepts that can be elegantly modelled by variants:

  • JSON
  • ASTs(Abstract Syntax Trees)
  • State Machines
  • Error Handling

Variant visitation

What is visitation?

Visitation can be defined as an abstraction that allows you to access the currently active variant alternative in an exhaustive and expressive manner. You are forced to provide some behaviour for all the types that the variant supports. Its expressive, because it doesn’t work through a chain of if-else; its a very elegant way of saying, for these types perform these actions.

 

by Blog Staff at October 22, 2026 07:54 PM

The public prerecordings for Meeting C++ 2026 are starting!

Meeting C++ starts with its yearly public recording events for the online track!

The public prerecordings for Meeting C++ 2026 are starting!

by Jens Weller

From the article:

As a hybrid conference Meeting C++ 2026 will feature an online only track. And you already are able to attend these talks prior to the conference!

The public prerecordings are meant to have an audience, and these are the first three events scheduled, all with 2-3 talks in one afternoon:
Tuesday, 27th October 15:00 (public Meetup Event)

15:20 Johan Vanslembrouck - Distributed programming with coroutines and asynchronous communication frameworks
16:40 Amlal El Mahrouss - Low-Level C++, Theory and Applications
Tuesday, 3rd November 13:45 (public Meetup Event)

14:00 Alexey Karelin - A Declarative Startup Model for Cortex-M Microcontrollers
15:20 Ivan Khodar - (N)RVO: What it is and how not to break it
16:40 Miloš Anđelković - Building the tiniest Pomodoro timer
Tuesday, 10th November 13:45 (public Meetup Event)

14:00 Koen Samyn - Zero Cost Scripting Languages For Game Engines With C++26 Reflection
15:20 - Mathew Benson - C++ Command Line IDE With Neovim
16:40 Joel Falcou - std::complex Ate My Performances! - Making Faster Hyper-complex Maths

 

by Meeting C++ at October 22, 2026 12:35 PM

The Daily WTF

Representative Line: Readable Formats

We all love format strings for generating human readable text. Certainly, they're a better choice than string concatenation. Even if I have a blind spot that keeps me from remembering the printf format tokens, I still prefer to use format strings.

Jasmine has a co-worker that does use format strings, but they also miss using string concatenation. So they've found a way to combine them, and avoid the perils of making readable code that describes the format of their text.

myField.DataFormatString = "{0:#,##0." + new string('0', 2) + ";(#,##0." + new string('0', 2) + ")}";

Now, in their defense, I can see how this code started its life. At some point, they wanted to make the number of decimal places a parameter. And sure, this is an easy way to do that and retain the intent, though this whole thing could be cleaned up with just a simple decimalPlaces = new string('0', 2), which would make the concatenation less confusing to read.

Related, while I was checking the documentation on the .NET formatting strings, I learned that they have a per-mille format specifier which requires writing a unicode sigil on most keyboards.

I'm sorry, but seeing string perMilleFmt = "#0.## " + '\u2030'; in my code would be TRWTF.

[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 October 22, 2026 06:30 AM

October 21, 2026

The Daily WTF

CodeSOD: Doing the Assignment

Today's code maybe isn't much of a WTF, but it does point in the general direction of, "Damn, you live like this?" Poor Nancy unfortunately does.

int x = 3;
int y = 4;
int z = 4;
x = y = z;

Each variable is declared and initialized, and then they're set equal to each other. It just raises the question though, why do it this way? Why not declare them and then x = y = z = 4, if we want that? Or maybe, for more clarity, int x = DEFAULT_VALUE; would be more legible, and we can skip the multiple assignments on one line. Why does x get set to 3 but then overwritten?

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

by Remy Porter at October 21, 2026 06:30 AM

XKCD

October 20, 2026

ISO C++

C++26: #embed -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGEmbedding binary resources in C++ has traditionally required external tools, scripts, or build-system workarounds. C++26’s new #embed directive changes that by letting developers include binary data directly at compile time with a simple, standardized approach.

C++26: #embed

by Sandor Dargo

From the article:

If you’ve ever needed to ship a binary file — a certificate, a small image, a default configuration — inside a C++ program, you know the ritual. You find or write a tool that converts the file into a C array, you wire it into your build system, and you pray that nobody forgets to re-run the conversion after updating the original file.

C++26 ends this with #embed (P1967R14 by JeanHeyd Meneide). Think of it as #include for binary data — a preprocessor directive that turns a file into a comma-separated sequence of integer constant expressions, directly at compile time, with no external tools.

Before #embed, every project rolled its own approach — xxd -i, objcopy, linker tricks, Python scripts, CMake file(READ) — each fragile, platform-specific, and one forgotten regeneration away from being stale.

#embed is also a perfect example of how long the standardization process can take. The first revision of P1967 was submitted in 2020, and it took fourteen revisions over five years before the committee voted it in. Along the way the syntax changed substantially as the design searched for consensus. And P1967 itself was a restart — earlier proposals like P1040 (std::embed) pushed for a non-preprocessor approach, embedding resources through a constexpr function rather than a directive. That path didn’t find enough support, and JeanHeyd eventually pivoted to the preprocessor-based design that made it through.

by Blog Staff at October 20, 2026 07:51 PM

Reducing C++ Template Bloat: Practical Exam -- Raymond Chen

RaymondChen_5in-150x150.jpgC++ templates can easily generate unnecessary code when lambdas are involved, since every lambda has its own unique type. Here, we take template-bloat reduction one step further by eliminating the template entirely and relying on a common callable type.

Reducing C++ template bloat by factoring out the type-dependent portions of the function, practical exam

by Raymond Chen

From the article:

A short time ago, we observed that there’s usually no need to wrap a callable in a lambda, and more recently observed that we can apply our principles for reducing C++ template bloat to simplify the function further.

Just to refresh our memories, here is where we left off:

template<typename Lambda>
bool Widget::QueueToWorkerThread(Lambda&& lambda)
{
    CreateWorkerThreadIfNeeded();
    return m_dispatcherQueue.TryEnqueue(
        std::forward<Lambda>(lambda));
}

by Blog Staff at October 20, 2026 07:38 PM

The Daily WTF

The Outage

At my employer, we use a service called Coveralls, which is a code coverage reporting tool that hooks into your CI pipeline. It takes your lcov reports and gives you some insights, and also makes it easy to cause the CI pipeline to fail if newly added code doesn't have reasonable coverage.

I have no strong feelings about the tool, but on February 24th, our CI jobs started failing, and our CI step that talked to Coveralls was the culprit. Coveralls had gone down. That happened to us, and a lot of other people. It was a widespread outage impacting anybody who used their service.

Coveralls actively published updates as the outage dragged on, and boy, did it drag on. Between them posting nearly identical updates minutes or even seconds apart and the general desperation that snuck into their outage notes after the first few days, I couldn't help but find their notes hilarious.

They've published their post-mortem, and the short version is that despite them paying their bills, Amazon decided they hadn't, and shut down their services. But it took them roughly 68 hours to figure that out.

If you scroll down past the post-mortem, you can see their outage notes. This is an unauthorized, dramatic reading of those notes. We've taken some liberties in interpreting it.

I hope this is taken in a good spirit, because they were just doing their best when this happened. I don't think most companies would be able to maintain operations when their cloud provider decides to lock their accounts. But I don't care who you are: begging your users to email you if they can help you migrate off AWS is funny.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

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

October 19, 2026

The Daily WTF

A Vat of Terrible Experiences

Taxes are a royal pain for everyone. Amazon has found a unique way to make them even worse, as Kris W. attests:

I recently bought a €9.61 kitchen knife on Amazon Spain. My card was charged €7.94 instead. After some investigation, I discovered that Amazon had applied an old VAT registration number I'd added to my personal account years ago, and had classified my purchase as a VAT-exempt intra-EU business transaction. The invoice even contained my business address from 2022, which no longer appeared anywhere in my account settings. I just wanted to remove the VAT number so I could go back to buying kitchen utensils without accidentally generating international tax paperwork.

European VAT Taxes

Unfortunately, Amazon no longer provided any visible way to manage that VAT number. Their customer support chatbot insisted I provide the order number from which I wanted the VAT number removed. A human agent confidently explained that I must have entered it into a secondary address field, and instructed me to delete and recreate my shipping address. Another support representative sent me an extensive list of documents I'd need to provide, including my passport, airline boarding passes, proof of export outside the EU, or my NATO identification card. Apparently removing a VAT number from an Amazon account is a process normally reserved for international travelers, Andorran residents, and military alliances.

Eventually, I found Amazon's official help page. It explicitly stated that VAT numbers could be removed either by contacting Customer Service or by creating an Amazon Business account to use the self-service option. After another round of correspondence, Customer Service informed me that they were not allowed to remove VAT numbers and instructed me to use the Business settings that my personal account didn't have. So I followed the documentation and created a Business account using my existing email address. During registration, Amazon required me to enter the very VAT number I was trying to remove, then promptly congratulated me by email on successfully adding and activating it.

But I couldn't access the Business settings yet. Amazon couldn't verify my business and demanded official documentation, so I obtained two freshly-issued certificates from two separate Spanish government agencies to prove that I was, in fact, a self-employed software developer. I uploaded both documents and waited. Eventually, my shiny new Amazon Business account was approved. I now had a separate Business account, complete with its own purchasing features and complimentary Business Prime membership. At last, I could navigate to the promised VAT-management page!

The page displayed my VAT number, confirmed it was valid, and offered a button to add more tax information. Beside the existing number, however, there was no Edit button. No Delete button. No self-service removal option whatsoever. There was only a link saying, Contact Customer Service to change your tax ID.

Naturally, the link led to a generic help center. After creating an entire business account, submitting government paperwork, and successfully registering the same VAT number a second time, I had arrived precisely where I started: Customer Service, which had already explained that it was not allowed to remove VAT numbers.

[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 Ellis Morning at October 19, 2026 06:30 AM

XKCD

October 17, 2026

ISO C++

A quick C++ standard container overview

Part four in the new C++ content series, visiting the heap. Meeting C++ 2026 is only 6 weeks away!

A quick C++ standard container overview

by Jens Weller

From the article:

The last entry looked at heap allocations, but one important part about heap allocations was missing: hidden allocations. Often you don't allocate directly, but a used class does. The C++ containers and string classes are the perfect example of this. Allocations for containers in the standard are done via allocators, which usually means heap allocations. These can be categorized as node based, chunk based and continuous memory containers...

by Meeting C++ at October 17, 2026 10:00 AM

October 16, 2026

ISO C++

The C++ fundamentals your seniors think they know -- Mateusz Pusz

Pointer provenance, the One Definition Rule, name lookup, and move semantics are not beginner topics. They are the load-bearing rules that decide whether code which compiles is actually correct. This is the opening article of a series on the ones experienced C++ developers most often get wrong, each post opening on a failure that reached production.

The C++ fundamentals your seniors think they know

by Mateusz Pusz

From the article:

Here is a five-second test. Ask an experienced C++ developer what new Connection{host} does, given a constructor that can throw. Almost everyone says “it calls operator new.” Almost no one names the new-expression: the language construct that first calls operator new to obtain raw storage and then constructs the object in it, two separate steps that the one keyword hides.

That gap is not trivia. It is why people write an operator new that tries to construct the object, cannot say who does the construction if operator new does not, cannot say who frees the storage when the constructor throws, and get caught out by placement new. The rule was there the whole time. Nobody ever pointed at it.

Published so far:

by Mateusz Pusz at October 16, 2026 07:40 PM

The Daily WTF

Error'd: Scrollpocalypse

Dr. Doom...scroller titled this one "Scrollbar-ception". Said he "Screenshot of the TikTok webpage (i.e. in a desktop browser) while not logged in. I swear this wasn't a NSFW TikTok video, instead it was a montage of some live show from some singer. Anyway... Back on the topic of the actual publishable snarky comments: Social media is known for doom-scrolling. Well, these are scrollbars of doom. Or doom-scrollbars."

d6711f9e7fb94f9ab616977c242562b2

An anonymous reader clarified "I was reorganizing the document by drag-and-dropping a bunch of table cells a bit too far for Word's comfort and it's telling me what I did wrong." Clearly.

01270f373b754d9f8cb520b5cd8ef856

B.J. H. reported a crisis. "First Southwest made me question the existence of my bags: I saw them scanned but the bag tracking system said there were no scans. Then the next page made me question my own existence as well." B.J. who?

08e657a929724b46b1f2c7289a928800

Adam R. reported a new way of formatting numbers. "Stripe has decided "You know what, I'll put the +/- sign for the transaction amount on the *previous* line instead of the same line, just for funsies." Less snarkily: line break algorithms are fickle, and they forgot to put a non-breaking space in there."

2ec536ec73504cc8bc237ef60664ed37

Peter S. proposed "I was trying to sell my Peleton equipment on their official "Repowered" site, and I was shown this nice list of yes/no buttons. I am not sure if I feel like gambling today with these answers." I want to know if Peter is unloading all his equipment because he reached his goals, or if he just gave up.

a40614615c714000846db94564b7e877

[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 October 16, 2026 06:30 AM

XKCD

October 15, 2026

The Daily WTF

The Frist Line of Defense

We don't cover a lot of security issues here, simply because they're not usually funny. But sometimes, they are. So here's a quick hit about some recent ones.

We start with a very bad month for the Danish social security system, the Central Register of Persons (CPR). Last week, they detected a breach which exposed the personal details of 8.8m people. Per the Register article, a cybersecurity specialist correctly pointed out that treating your ID number as if it were a secret was a terrible idea in the first place, but unfortunately, so many systems have grown up around the idea that full knowledge of your state issued ID number as proof of identity, that the security expert is screaming into the wind. They're right, but it's going to take a lot to change.

Okay, Denmark's social security service was hacked. What's so funny about that?

Well, the mechanism of the hack appears to go thusly. First, third party companies have access to the database, which they can use to send notifications to their customers via CPR. That connection is secured with a password, and one of those third parties secured their account with the kind of password you'd use to protect the precious air of the planet Druidia. Also known as the kind of password some idiot would put on their luggage: "123456". (paywalled, Danish article).

The hacker accessed the system on September 10th, and spent ten days searching through the system. The intrusion wasn't detected until October 2nd, when CPR went to send an invoice to the third party company and noticed, "Boy, that's more searches than they have customers." Now, obviously, CPR should have never even allowed such a low complexity password, but also, the third party company shouldn't have used such a low security password.

Now, if you'll excuse me, I have to change the combination on my luggage.

In other news, I'm not particularly fond of blockchain stuff. Mostly, the whole distributed ledger seems like a solution in search of problems, and "trading tokens as if they're money" is the best thing anybody's been able to come up with. Back in my consulting days, when blockchains were all over the news, I was consulting with a large retailer, and they were exploring using blockchain in their supply chain. "How does that work?" I asked innocently. "It'll have blockchain in it." "Sure, but what does the blockchain get you?" "We'll be using blockchain. If there's like, an e. coli outbreak, we can trace where it came from." "Couldn't you get that out of a regular database?" "But this'll have blockchain."

In any case, blockchain companies getting hacked and having all their users' assets stolen is practically a daily occurrence. Not really notable. But a recent hack is legitimately interesting.

A company, called Ledger, sells "hardware wallets". Instead of storing your keys on some third party's servers (where it'll get hacked and you'll lose all your "money"), you store them on a hardware device that you put in a safe. It's not connected to the internet, and thus is unhackable. Or so you'd think. But if enough people are buying those devices, a supply chain attack becomes potentially very lucrative. And that's exactly what happened. Someone in the supply chain cracked a bunch of these devices open, and inserted new hardware. They attached a microcontroller to the screen leads, that allowed it to read what was on the screen (and thus detect when the screen was displaying a recovery code that could be used to access the wallet), and a cellular modem that allowed it to literally phone home with that information.

In total, these hackers walked away with the equivalent of nearly $100M in cryptocurrency.

All the devices passed through Ledger, where they were inspected before being sold. Presumably, they were sealed with tamper-resistant packaging. It's plausible that the tamperer was downstream from here and the customers didn't fully inspect the packaging. Even your most savvy user generally doesn't check that kind of thing, and I suspect a lot of these customers aren't actually all that savvy. But also, companies in the crypto space tend to be... we'll say, more eager than cautious, so I wouldn't be surprised if the tampering happened upstream and didn't get caught by their inspection process.

Security is hard in the best case. It's much harder when you're putting the final onus of security on end users who may have thousands or even millions of dollars locked behind a single key. Or when passwords are hard, so you pick an easy one to remember.

[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 October 15, 2026 06:30 AM

October 14, 2026

ISO C++

On Contracts and Safety -- Lucian Radu Teodorescu

logo.pngComposing safe functions may not be safe. Lucian Radu Teodorescu explores how C++26 contracts help uncover problems.

On Contracts and Safety

by Lucian Radu Teodorescu

From the article:

If two operations are safe, is their composition safe too? At first glance, the answer ought to be yes. But a small expression such as f(g(10)) can appear to contradict that intuition: both functions may be safe under their own contracts, while the nested call still violates memory safety. The missing piece is the caller. Safety does not compose merely because expressions are nested; it composes when obligations and guarantees line up at each boundary.

Building on the previous article [Teodorescu26], this article looks at how contracts help us build safe programs. Contracts give us a structured way to describe obligations and guarantees, both at software boundaries and inside implementations. In that context, we briefly describe C++26 contracts.

We then look more closely at a common source of confusion around the composability of safety. We also consider enforced safe operations as a practical way to build safe programs with respect to selected safety properties. Finally, we look at documentation contracts as a complementary way to express contracts that do not belong in code. Both forms help build safety into applications.

Contracts

‘Design by Contract’ is the discipline of making the obligations and guarantees of software components explicit [Meyer91]. A routine may impose preconditions on its callers, promise postconditions on return, and preserve invariants associated with the object or module it belongs to. The main point is not just that these predicates may be checked, but that they make the boundary between client and implementation explicit.

C++26 contracts bring part of this discipline into the language [P2900]. The core idea is that users can add contract assertions to programs, providing machine-checkable statements about expected program behaviour. These contract assertions come in three forms: preconditions, postconditions, and general-purpose assertion statements.

by Blog Staff at October 14, 2026 07:36 PM

The Daily WTF

Representative Line: A Diamond in the Rough

Mandy's co-worker recently learned about virtual inheritance in C++. It's become their new favorite button to push, and they only use virtual inheritance.

Virtual inheritance is one workaround for the "diamond problem", where you have an inheritance tree that "recombines" via multiple inheritance: when a child class has a Hapsburg-esque parentage, it's hard to decide which inherited methods are being invoked or overridden.

In C++, imagine you have class A, which gets derived into classes B and C. Class D then uses multiple inheritance to inherit from B and C. In practice, this means that D inherits from A twice, and would have two internal copies of all of A's members.

If, on the other hand, you have B and C inherit virtually (class B : public virtual A), then class D will only actually inherit a single copy of A.

If you're reading this and going, "Boy, this just sounds like another reason to avoid multiple inheritance," you're probably right. The important thing, though, is inheriting virtually impacts how your child classes will inherit. It only matters if you have child classes.

Which brings us back to Mandy's co-worker. He read somewhere that defaulting to virtual inheritance all the time was safer, so he did that all the time. All. The. Time.

Including in this case:

class SomeSpecificDerivedClass final : public virtual SomeBaseClass

The class here is marked final. It can't be inherited from. The use of virtual accomplishes nothing.

[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 October 14, 2026 06:30 AM

XKCD

October 13, 2026

The Daily WTF

Editor's Soapbox: Digital Mail

Ever get some special letter, card, or picture from a friend or loved one that you held onto, maybe even taped to your cube or office wall? Is it something you still look at fondly, something that lifts your spirits whenever you're down? Certainly, a thoughtful card or letter is much nicer than a thoughtful email.

Now imagine your special keepsake being scanned, censored, and converted into a digital file that you can only view from a tablet — assuming you can afford the fee to access the tablet. The original has been destroyed; it's gone forever. You'll never get to see or feel it in your hands.

Birthday Card, 30 October 1943, page 2 of 2

It sounds almost too cruel, like something you'd find in a Fallout game. Unfortunately, it's reality for more and more people incarcerated in US prisons.

I've been writing to an incarcerated person for a while now myself. I find the process incredibly rewarding; I think about my friend all the time and wish them well. Unfortunately, the scanning and processing takes absolutely forever, so in a given year we only exchange 3 letters per side. The digitized files that I receive have names censored out of them; I have no idea what's removed from my letters before my friend receives them. For me, this is all too reminiscent of exchanging letters with my grandmother in Iran before she died. Agents there would straight-up open the envelope, confiscate any valuables inside, marker over anything they didn't like, then re-seal the envelope and send it back on its merry way.

Over 30 US states now digitize the mail passing in and out of prisons, relying on AI to judge what's kosher and what isn't. If you thought AI was great with resumes, just wait until you task it with threat detection! It's been working so well that one nonprofit organization had to change its name: the word fight, used in any context whatsoever, gets flagged.

Once mail is scanned, it's only accessible by tablets that have to be paid for. Incarcerated people are already nickled and dimed for a ridiculous number of things and surely don't need more fees.

It doesn't stop at mail, either. The latest tech is also being used to eliminate physical visitation. Because if there's anything the pandemic taught us, it's that nothing beats seeing your loved ones exclusively on a screen for years at a stretch.

The states justify these egregious measures by playing the drug card. They're necessary to stop drugs from entering the prisons. But these states stop short of providing evidence to show that these tech-facilitated practices are actually having the intended effect. Even if they magically solved drug trafficking forever, could any result truly justify the vast harm being inflicted upon incarcerated people, their families, and their friends? Physical mail and visitation are necessary lifelines and psychological boosts for those who might otherwise have nothing and no one to hold onto during an unimaginably difficult time of their lives.

Do I really have to explain the benefit of parents and children exchanging homework, letters, and pictures?

I'm angry about this on so many levels. If you are, too, here's some stuff we can do to fight work against this together:

  • Support prison abolition with your time, money, and/or IT superpowers. Forced prison labor is slavery. The entire punitive model is cruel, biased, and far less effective than approaches like restorative and community-based justice. Moving on is long overdue and the best way to make all of this stop.
  • Avoid working for companies that facilitate these practices. Tell your friends not to work for them, either. If you're stuck working for them for survival's sake, look for ways to enact positive change from the inside.
  • Spread the word of what's happening. Most people have no idea. Use your knowledge to educate technical and non-technical folks. They might want to do something about this, too.
  • Write to incarcerated people yourself. Like Bob Ross said, "Everybody needs a friend." Knowing there's someone in your corner who cares about you makes all the difference in the world. Sites like WriteAPrisoner.com will match you up with a pen pal.

A drop of water seems harmless, but get enough of those together and you carve out the Grand Canyon. If we all do something to help, however big or small, our massed effort becomes something powerful. As tech professionals, we are especially empowered to push back on these cruel and abusive practices. We must act now, before they move out of prisons and into mainstream society.

Do you want your post office to start doing this?

Sources:

[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 Ellis Morning at October 13, 2026 06:30 AM

October 12, 2026

ISO C++

C++26 Reflection: Simplifying JSON Serialization -- Vivek Bhadra

C++26 reflection opens the door to eliminating much of the repetitive, error-prone code involved in JSON serialization. In this post, we’ll build on the basics of reflection and explore how it can automatically map the members of a user-defined class to JSON, even as the class evolves.

C++26 Reflection: Simplifying JSON Serialization

by Vivek Bhadra

From the article:

In the previous post I have discussed the basic usage of C++26’s latest (still experimental) feature called reflection. In this post we will look into a more concrete problem which many of us have come across called JSON serialization. We often receive the data in the form of an object of a user defined class. And what we need to do is to format it in JSON format which means to associate the data member names in the class definition with their respective values and put them in a JSON structure. First lets have a look at a hypothetical CanDataSource class as below:

 

by Blog Staff at October 12, 2026 07:31 PM

Releasing the full program of Meeting C++ 2026

The full program of Meeting C++ 2026 is now available:

Schedule of Meeting C++ 2026

The full Meeting C++ 2026 program is released

by Jens Weller

From the article:

appy to announce that all slots in the program for Meeting C++ 2026 are now filled!

With that the schedule for this years conference is complete! Most of it has been visible already for months, there are a few minor editions, ... like the keynotes:

    Mateusz Pusz - Why Great C++ Libraries Fail (And How to Fix That)
    Kate Gregory - Brains And Belonging

 

by Meeting C++ at October 12, 2026 02:00 PM

The Daily WTF

CodeSOD: A Type of Type Safety

For some godawful reason, people like to explain object oriented concepts via analogy to biological taxonomies. I suppose it's easy to understand an "is-a" relationship (a cat is a mammal), but the down side is you get a complex and increasingly leaky analogy that over-emphasizes the importance of inheritance.

That's not to slight Alan's choice of using it to anoymize today's code. It's just a broad frustration on my part.

In any case, Alan has been working in a C++ codebase that's written by people who maybe don't fully understand all the key object oriented concepts. That's why you get code like this:

    /*
     * If possible, steal tentacle from the given animal.
     */
    void Animal::StealTentacle(Animal *animal) {
        // only Octopus and Squid can have tentacles
        if (!IS_INSTANCE_OF(this, Octopus) && !IS_INSTANCE_OF(this, Squid)) {
            return;
        }

        Limb *limb = animal->mLimbs->GetFirstTentacle();
        if (limb) {
            limb->AttachToAnimal(this);
            // . . .

This function takes a raw pointer to an Animal object. If that pointer is not an Octopus or a Squid, we bail. Otherwise, we're going to take its tentacle, and do stuff with it.

Now, this is a pretty clear example of the type switch anti-pattern. Instead of using the type system and polymorphism to enforce restrictions, we instead do runtime type checks.

But wait a second, what's going on in that IS_INSTANCE_OF?

    // I've noticed that dynamic_cast always returns a valid result when
    // casting an "objectPointer" of type "className".
    // Try casting it to a [Organism *] to force it to work. (?)
    #define IS_INSTANCE_OF(objectPointer, className)    ((bool) (dynamic_cast<className *>(((Organism *) objectPointer)) != NULL))
    #define IS_MEMBER_OF(objectPointer, className)      IS_INSTANCE_OF(objectPointer, className)    // temporary macro alias

This code attempts to take an objectPointer and first, force it into a pointer to our base type (Organism), using a C-style cast. Now, in C++, C-style casts are a shorthand, and the compiler will, based on the context, attempt to do the best cast which fits the situation, starting with a const_cast (which only alters the constness of the type), and failing all the way up to a reinterpret_cast- which just ignores type information entirely and assumes you know what you're doing.

Which this developer clearly doesn't.

In any case, we pass the C-style cast result into the dynamic_cast function, which attempts to cast that pointer into an instance of className. If no such conversion is possible (because they're not part of the same inheritance hiercharcy), it returns NULL, which is what they're checking.

Their comment highlights their misunderstanding of the function; dynamic_cast can be used to crosscast. In other words, dynamic_cast<Dog*>(my_cat) will actually work, because (in this example) Dog* and Cat* share a common base.

From the docs:

Otherwise, if expression points/refers to a public base class subobject of the most derived object, and the type of the most derived object has an unambiguous and public base class of type Target, the result points/refers to the Target subobject of the most derived object. In other words, dynamic_cast can be used to crosscast (or side-cast) pointers/references, between two types derived from the same base.

You shouldn't be using dynamic cast to solve this problem. Hell, you sohuldn't be doing any of this in the first place!

In any case, in actual usage, the developers responsible do stuff like this:

    if (IS_INSTANCE_OF(animal, Felid)) {
        Felid *cat = (Felid *) animal; // Yes another C-style cast - this time (hopefully) devolving to the same dynamic_cast hidden inside the expansion of the previous macro.

I love when a comment says "hopefully". "This hopefully does what I think it should do".

I'll let Alan summarize the problems:

Used prudently, the dynamic dispatch facility that object oriented languages provide their users can be a valuable tool for capturing the domain model in clean, elegant code. However, as even C++'s designer Bjarne Stroustrup acknowledged, in "The Design and Evolution of C++", the introduction of support for Run-Time Type Information makes it possible to spurn such assistance and write RTTI-based code for which a verdict of "combines the syntactic elegance of C with the run-time efficiency of Smalltalk" is just "too kind".

[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 October 12, 2026 06:30 AM

XKCD

October 09, 2026

ISO C++

C++26: Reducing undefined behaviour -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGC++26 continues the language’s push toward safer, more predictable code by reducing situations that can lead to undefined behaviour. This article looks at several key changes that turn dangerous runtime surprises into diagnosable errors or well-defined behaviour.

C++26: Reducing undefined behaviour

by Sandor Dargo

From the article:

Nowadays, safety is in the focus of C++. Whether it’s at committee meetings, conference talks, or hallway discussions, the topic keeps coming up. C++26 made some big steps forward in this area, and one recurring theme is the reduction of cases leading to undefined behaviour.

With the words of one of the presented proposals, “undefined behaviour has all but unbounded potential for bad program behaviour, including security leaks, data corruption, deadlocks, and so on”. The simple act of violating a precondition can silently turn a perfectly correct-looking program into one that exhibits any of these.

In today’s article, we look at how and where C++26 addresses this. A couple of these changes we have already covered on this blog, but they are worth reiterating in this context. And there is one important change we haven’t talked about yet. Let’s start with that.

P3144R2: Deleting a Pointer to an Incomplete Type Should be Ill-formed

Before C++26, deleting a pointer to an incomplete type was undefined behaviour. The only exception was when the complete class type happened to have a trivial destructor and no class-specific deallocation function. In all other cases, the compiler simply could not know what to do.

by Blog Staff at October 09, 2026 07:49 PM

The Daily WTF

Error'd: Fast Quick

Matias shared a standard sort of flubstituted fail-merge error'd; not really egregious, just routine. "I am {{emotionType}} to hear this."

38cbfe9d47c3447790831d94826212c8

And another mail-not-merged from Reinier B. "When the package from [SELLER] seemed to be lost in the mail, I was very [EMOTIONAL_STATE] with the refund of [AMOUNT]. I can now buy another [ITEM] instead."

566b877339174759b96eaa3aa5b8a032

Dave A. didn't care for this mail flub, though it's hardly egregious in my opinion. He suggested we just label it with "A short description of snarky comments."

6e07443194d549519ed3cff7ddfba009

"I've_missed_you_too" Willy wrote in response to this earnest email. "Long lasting relationships with car dealers are built on the personal touchÖ."

7fb868d3282c4229aff2d94814247705

"This is a title" Peter said about a polyglot web page. "This is a comment."

492453f2f3c741dcbd0d0b194a4a2815

[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 October 09, 2026 06:30 AM

XKCD

October 08, 2026

ISO C++

The Daily WTF

Racing Trains

Robert G sends us a WTF from the outside, but I think we can come up with some hypotheses about what actually happened.

Robert was traveling by train. For complicated train reasons, the car he was seated on was not actually scheduled to continue with the train he was booked to ride, the replacement car missed its scheduled arrival, and the result was that Robert was left at a station needing to rebook his travel.

Now, given that this is in a region of the world with a fairly robust train network, this represented a hiccup of thirty minutes in a many hour trip. Not a particularly big deal. But Robert didn't want to get stranded any longer than he had to, so he took out his phone, fired up the train company's app, and made sure he had a reservation on the next train. He got the confirmation, and grabbed a coffee while he waited.

Not quite thirty minutes later, Robert boarded the train and went towards his reserved seat. Another passenger approached from the opposite direction, and they met at the seat. "Excuse me," Robert said, "but I reserved this one."

"No, I reserved this one."

Being reasonable people, they both pulled out their phones and pulled up their apps. Sure enough, each one of them was confirmed for that seat. Since the email confirmation had more details than the app provided, they both pulled up the email. Same seat. Both confirmed. The timestamp of the reservation? The same, down to the second.

"I don't think the conductor will let us sit in each other's laps," the other passenger said.

As it turned out, there was enough room on the train that no lap sitting was required. Everyone got a seat, even if it wasn't the one they reserved.

But the story stuck with Robert. A major transit provider had a reservation system that clearly had a race condition. It seemed like the most basic example of race conditions too, the kind you're shown in college to explain the basic concept.

"Check if the seat is reserved, and if it's not, reserve it." Because that sequence isn't atomic, two different threads could do the check, see it's not reserved, and then reserve it. I suppose it's at least something that one reservation doesn't overwrite the other, which at least indicates that a reservation is its own record.

The real question is this: this has to happen with some frequency, so how has nobody fixed it?

The real answer: they probably just don't care, either because they literally don't care, or because their software is such a trashfire that this doesn't even rise to the top ten bugs. It's likely a mix of both.

[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 October 08, 2026 06:30 AM

October 07, 2026

The Daily WTF

CodeSOD: A Tool for You

A junior dev on the team had a simple question: in Java, how do I correctly read user input from the CLI and act on it?

Now, we can wonder about a junior dev not having such basic knowledge, but maybe they're new to Java specifically. Who knows. But Robert's team has a senior on it who "likes to mentor". This senior has strong opinions about how to write software, extreme confidence in those opinions, and has somehow been around the company long enough that he knows where the bodies are buried and no one will fire him.

Here's his sample application for reading input.

import java.nio.charset.StandardCharsets;
import java.util.*;

public class ScannerTool {
  public static void main(String[] args) {
    Map<Optional<Character>, Map.Entry<String, Boolean>> map = new HashMap<>();
    map.put(Optional.of('A'), new AbstractMap.SimpleEntry<>("You entered A.", true));
    map.put(Optional.of('B'), new AbstractMap.SimpleEntry<>("You entered B.", true));
    map.put(Optional.empty(), new AbstractMap.SimpleEntry<>("You entered nothing.", false));
    Optional<Character> input;
    do {
      System.out.println("Please enter A or B:");
    } while (!map.getOrDefault((input = nextCharacter()), new AbstractMap.SimpleEntry<>("", false))
        .getValue());
    System.out.println(map.get(input).getKey());
  }

  public static Optional<Character> nextCharacter() {
    String l = new Scanner(System.in, StandardCharsets.UTF_8).nextLine();
    if (l != null && !l.isEmpty()) {
      return Optional.of(l.charAt(0));
    }
    return Optional.empty();
  }
}

Look, I know Java is verbose, but this is entirely next level. Giving this to a junior has to constitute an attempt to drive the youth out of the industry, because any sane person being told, "your job is to write this" would realize they've committed a grave error in their career choice and needs to escape now.

nextCharacter in this case actually returns the first character of the next line, not the next character. And if there isn't one, it returns an empty optional. Which, fine, we only expect one character per line of input for this exercise, so that's not wrong, I just don't like the name of the function.

Of course, using Scanner here is a wrecking ball fly swatter- that class is a full on parser for reading out common data types from a file. Worth showing to a junior, but a little out of scope of this question.

But the real overengineering is the map of maps- well, a map of map entries. The key to the outer map is an optional of the character that was entered by the user. The value is itself a map, the key of the map is the message we want to output, the value is whether or not the loop should continue. They've reinvented tuples using map entries. Which, in their defense, mainline Java doesn't have tuples (enterprise edition seems to have them in the javax namespace, but I'm not even certain those are meant to be general purpose tuples anyway). A quick search indicates that their absence is a perennial source of heated discussions in forums and Stack Overflow.

Robert writes:

It is remarkable in its creativity and execution and still has me in awe. When I tried to unpack it, my brain just started to pack up its things and left, haven't seen it since.

Bon voyage.

[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 October 07, 2026 06:30 AM

XKCD

October 06, 2026

ISO C++

How fast is C++26’s std::hive? -- Daniel Lemire

si3ao-825x510.jpgC++26 introduces std::hive, a new container designed to combine stable references and efficient erasure with better memory locality than a linked list. But where does it actually fit performance-wise compared with std::vector and std::list?

How fast is C++26’s std::hive?

by Daniel Lemire

From the article:

C++26 adds a new container to the standard library: std::hive. It is meant to occupy the ground between std::vector and std::list. Like a vector, it keeps its elements in contiguous blocks of memory, so scanning it does not require you to chase a pointer for every element. Like a list, it never moves an element once it has been inserted: your pointers, references and iterators stay valid, and you may erase any element in constant time without disturbing the others.

Internally, a hive is a linked list of blocks. Each block carries a skipfield: a small integer per slot that tells the iterator how many erased slots to jump over.

No standard library ships std::hive yet to my knowledge. Fortunately there is an implementation (plf::hive by Matt Bentley) as a single header file that you can use today.

I use elements of type uint64_t, GCC 16.1 with -O3 -march=native, on an Intel Xeon Gold 6548N (Emerald Rapids), pinned to one core. Numbers are nanoseconds per element, along with the cycles and instructions retired per element.

We start from an empty container and append a million values. The container is then destroyed.

by Blog Staff at October 06, 2026 06:09 PM

The Daily WTF

CodeSOD: A Random Article

Many years ago, DJ got his start doing odd web development jobs for a low hourly rate. He was only 19 when he got started, and what he lacked in experience he made up for in being cheap to hire.

As I said, that was many years ago, and he has since learned a lot. But he still has some code from his very first "someone paid me for this" project. This particular function needed to pick a random bit of content from their database to display in the "right side" banner area. This is how DJ implemented it.

// Create an array of all the ID's used
$int = array();
$query = $sql->query("SELECT * FROM rightside");
while($row = $sql->objects('',$query)) {
    $int[ $row->id ] = $row->id;
    if ($row->id > $max) {
        $max = $row->id;
    }
}
                
// Find a random ID that has been used
$x = false;
while ($x == false) {
    $rand = rand(0,$max);
    foreach ($int as $thing) {
         if ($thing == $rand) {
 $x = true;
         }
    }
}

$query = $sql->query("SELECT * FROM rightside WHERE id = ".$rand);

We start by building an array. Then we query the database for all the content. We get all the rows and columns, butw e only are interested in one- the id. We create a sparse array, where the index of the item is the item's value. We also track the max.

Once we've got that, we start a loop. Inside that loop, we generate a random number, check if it's in our array by doing a foreach across the array, and if it is, we break the loop- we've found our random content. If it's not, we keep trying until we score a hit.

Finally, we construct our query with string concatenation and grab the content we want to display.

Now, as a true confession, there's an element of caveat emptor here; if you're hiring the kid from the local college and paying them a few bucks an hour, this is the kind of thing you get.

Is the code terrible? Yes, even by early-00s PHP standards. Is it really DJ's problem, though? No. I'd hope any of us would look back at the code we wrote when we were 19, and shudder. It means we've learned something in the interim.

For this confession, I say there's no need to atone. Hopefully everyone learned a lesson, especially the company trying to hire programmers on the cheap.

[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 October 06, 2026 06:30 AM

October 05, 2026

The Daily WTF

CodeSOD: The Date and Time and Time

Today's anonymous submitter sends us some legacy Java code.

The task is this: check what time it is. And fortunately, even in the older Java datetime libraries that were terrible, this was an easy task. You just needed to do something like new Date(), which constructs a date time object set to the current time. getTime() picks off just the time portion.

Or, you could do this.

Timestamp current = new Timestamp(new Date().getTime());
Date date = new Date(current.getTime());

This creates a date, picks the time off, populates a timestamp, gets the time from the timestamp, and constructs a new date object.

The old Java date classes were awful, but they never needed you to do this. This is entirely home grown ugliness.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

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

XKCD

October 02, 2026

ISO C++

The Prompt-Wait-Evaluate Loop: How AI Kills Flow Without You Noticing -- Sandor Dargo

 

SANDOR_DARGO_ROUND.JPGAI coding assistants may help us produce more code, but they can also quietly change the way we experience the work itself. The constant prompt-wait-evaluate cycle can disrupt the deep focus that makes programming engaging, turning what looks like productive work into a series of subtle interruptions.

The Prompt-Wait-Evaluate Loop: How AI Kills Flow Without You Noticing

by Sandor Dargo

From the article:

A few months ago, I wrote about finding joy in programming in the age of AI. In the personal discussions I’ve had with fellow developers — both before and after that article — one thing keeps striking me. Most people don’t argue. They just say: yes, that’s exactly how it feels.

But a question kept coming up in those conversations: why does it feel this way? Not in the philosophical sense — I covered that. In the mechanical sense. What is actually happening to our attention when we work with AI coding assistants?

I want to explore that topic more deeply, because I think understanding the mechanism matters. It’s the difference between vaguely sensing that something is off and being able to do something about it.

What flow actually is

In 1990, the psychologist Mihaly Csikszentmihalyi published Flow: The Psychology of Optimal Experience, the book that gave a name to what probably all of us had already experienced. Flow is the state of full absorption where action and awareness merge. You lose track of time. Self-consciousness fades. The work just happens.

by Blog Staff at October 02, 2026 06:06 PM

Lets explore the stack

The second post in a new blog series at Meeting C++!

Lets explore the stack

by Jens Weller

From the article:

Part two in the new C++ content, as I've spend some time creating content to be now released in front of Meeting C++ 2026.

Maybe read last weeks post About alignment, struct layout and the cache first.

Maybe its a good idea to continue in an area which a lot of other things build upon: the stack, followed by the heap and visiting RAII. Modern programs usually have other memory areas too, like read only sections or a place where static text is stored. Exploring these is also fun, but gets one into an area ruled by the OS and hardware dependent memory layout. Which may differ between the wide range of C++ usage...

 

by Meeting C++ at October 02, 2026 04:26 PM

The Daily WTF

Error'd: 12345

We have for you this week a full set of the Error'd we most love to hate: the perverse password policy.

An anonymous reader drops this, with little to say except to note "Speciaal passwords". Evidently they supplied a password which satisfied each of the five green critera, but still it was rejected. It would be nice to know where this offense originated,

cc110e101f8d49be9a4cdc4f06610701

Intrepid Michael R. explains "note: Handy is the German term for mobile phone (UK) or cell phone (US)."

a435f504c19d4e5cac50b7b70bd78648

Sacha R. observes a secret policy at play, saying "Oracle try to do the right thing by showing you the password policy requirements when you manually reset a password in their Fusion applications. It's just a pity that it doesn't show you the *correct* password policy requirements."

a5f15cdcbd194c62bb43fac49090df0f

"Faith, here's an equivocator," reports Matthew S. "Pick one, Staples!" I bet it's the ampersand that offends.

ebc7f35e5c1b4b748ec395265b154ce7

"At least letters or numbers?" questions a final anon. "Just a little head scratching moment. After removing all special characters from the password I was able to register." This looks like partly a translation wtf and partly a software design wtf.

ecaab92f40c64cfcbe4eca13aa0fe418

[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 October 02, 2026 06:30 AM

XKCD

October 01, 2026

The Daily WTF

CodeSOD: Very Valid Tokens

Today's anonymous submitter shares with us the function their company uses to validate authentication tokens.

public bool IsTokenValid(string token)
{
    //TODO
    return true;
}

This is running in production. So that's fun. The user they've authenticated as is tracked separately at the start of their session, which makes it at least marginally harder to pretend to be someone you aren't, but for authentication, any token will do.

[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 October 01, 2026 06:30 AM

September 30, 2026

ISO C++

Beautiful Type Erasure with C++26 Reflection -- Ryan Keane

avatar.jpgC++26 reflection opens the door to rethinking patterns that traditionally require mountains of boilerplate, including type erasure. The rjk::duck library puts that capability to work, using reflection to provide flexible, customizable type erasure with the performance of traditional vtable dispatch.

Beautiful Type Erasure with C++26 Reflection

by Ryan Keane

From the article:

If you’ve ever tried using type erasure for something more complicated than std::any or std::function, you’ve either written 100+ lines of easy-to-mess-up code or reached for a boilerplate-heavy library like Boost.TypeErasure or Folly.Poly. rjk::duck uses the magic that is C++26 reflection to remove these pain points while preserving all of the customization and performance.

Consider the following basic example:

#include <rjk/duck.hpp> // ...

struct [[=rjk::trait]] Container {
    auto size()  const -> std::size_t;
    auto empty() const -> bool;
    auto clear()       -> void;
};

rjk::duck<Container> c{std::vector<int>{1, 2, 3}};
c.size();   // 3

c = std::string{"hello"};  // swap underlying type at runtime
c.size();   // 5

c = std::map<int, int>{{1, 2}, {3, 4}};
c.empty();  // false
c.clear();
c.empty();  // true

 

 

by Blog Staff at September 30, 2026 06:02 PM

Upcoming C++ User Group meetings in September 2026

The monthly listing of upcoming C++ User Group meetings.

Upcoming C++ User Group Meetings in September

by Jens Weller

From the article:

The monthly overview on upcoming C++ User Group meetings! C++ Brno Meetup is a newly registered group having their 10th meetup!

If you'd like to start your own C++ User Group, one of the best places to get started with your network is Meeting C++ 2026 in Berlin, Meeting C++ is also happy to support your new group. You can also find various articles about starting and running in the user group section of Meeting C++.

 

 

by Meeting C++ at September 30, 2026 04:26 PM

The Daily WTF

CodeSOD: Quite a Distance from the Right Solution

Fritz's team needed to see if one point was within a certain distance from a center point. You or I would likely try and answer this question using a simple distance calculation, since that's the question we're trying to answer. But what if you didn't understand distances at all? Then you could write this little piece of genius.

        private bool IsWithin(Point point, int radius)
        {
            for (int x = -radius; x < radius + 1; x++)
            {
                for (int y = -radius; y < radius + 1; y++)
                {
                    if ((PositionX == point.X + x) && (PositionY == point.Y + y))
                        return true;
                }
            }

            return false;
        }

This limits us to integer point values, which itself is fine. This iterates across every coordinate from (x-radius,y-radius) to (x+radius,y+radius) and checks if any of them are equal to our center point, (PositionX,PositionY). Notably, this means we're not checking a radius, at least not in a traditional metric, we're checking a box (or using the taxicab metric). Which if we wanted to check a box, we actually have even easier math than the distance equation- we could do that with pure bounds checking.

I've never thought to try and brute force distance checking, and that feels like a failure of my own creativity. Fritz's team mate at least was able to WTF in a way I wouldn't have considered.

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

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

XKCD

September 29, 2026

ISO C++

Boost 1.92.0 is out.

space.pngspace.pnggetboost.png

Boost 1.92.0 is out. Highlights from this release:

GPU / CUDA

  • Charconv: to_chars and from_chars for integers are now usable inside CUDA kernels.

  • Decimal: decimal32_t, decimal64_t, and decimal128_t are now usable in CUDA kernels.

  • Math: fixed CUDA compilation where host functions were incorrectly marked as device.

Networking hardening

  • Beast: stricter HTTP parsing. It now rejects Content-Length combined with Transfer-Encoding regardless of field order, rejects chunked encoding in HTTP/1.0 requests, validates quoted strings in chunk extensions, and drops framing and connection fields carried in trailers. The dependency on Boost.Functional was also removed.

  • URL: third round security review fixes, including a heap buffer overflow in normalize_path for authority-less URLs and an uninitialized read in ipv6_address_rule.

Containers and data structures

  • Container: new hub container designed by Joaquín M. López Muñoz. Also adds unchecked_emplace_back and unchecked_push_back to vector, static_vector, and small_vector.

  • Lockfree: two new queues, mpsc_weak_queue (MPSC) and bounded_ticket_queue (ringbuffer based bounded MPMC). Both have explicit progress caveats: neither is strictly lock free under all configurations.

  • Unordered: C++20 ranges interop across all containers (insert_range, std::from_range construction, and associated CTAD).

  • Graph: Louvain community detection for modularity based clustering.

  • Hash2: built in support for std::optional, std::variant, and std::monostate.

C++20 modules

  • New module support in Conversion, DLL, LexicalCast, PFR, Stacktrace, and TypeIndex.

Build system

  • Windows .dll files now install into the binary directory by default (previously the library directory, except on Cygwin). A new --dlldir option overrides this.

  • The CMake config installed by b2 install now supports header only libraries as find_package components, so find_package(Boost REQUIRED COMPONENTS mp11) works and defines Boost::mp11.

Deprecations and breaking changes

  • Heap and Lockfree: this is the last release to support C++14. Future releases require C++17.

  • MSM (backmp11) has several breaking changes, notably that events in process_event are no longer enqueued automatically. Use enqueue_event in actions instead.

 

Full notes and downloads: https://www.boost.org/releases/1.92.0/

 

by Blog Staff at September 29, 2026 07:57 PM

The Daily WTF

Representative Line: Unique Testing

Nikolai M's team had a flaky CI/CD build. About 0.5% of the time, one of their tests would fail: frequent enough to be annoying, but not so frequent that it motivated management to assign anybody to investigate. Nikolai eventually dug in, taking the initiative.

Microsoft's implementation of UUIDs calls them GUIDs. The GUID is, per the docs, really just a wrapper around UUID algorithms, and supports a variety of different UUID variants. I'm sure at some historical point, this wasnt't true, and Microsoft had some weird internal algorithm. That's not really here nor there, but the test that was failing was failing because of an assertion relating to GUIDs.

Assert.DoesNotContain("000", transactionId.ToString());

transactionId is a GUID. This line converts it to a string and checks if it contains "000". They're attempting to check if it's an empty UUID, and they've assumed that three sequential zeroes in the output would be an impossible event. This is untrue. Nikolai measured it, and found it happens 0.5527% of the time- 1-in-181.

So this is a bad test, and could be made better with a more thorough check. Or it could leverage the built in constant GUID.Empty, which is a UUID where every bit is zero.

And it's that which really bugs me, honestly. Even if you didn't know about the constant, the idea of constructing an empty GUID seems like the obvious choice. Though I suppose you'd have to check the docs to find out how to construct a GUID directly, and if you're already reading the docs, the chances of you seeing the built-in constant are probably higher than 0.5527%.

[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 September 29, 2026 06:30 AM

September 28, 2026

ISO C++

HPX V2.0.0 RC1 released -- The HPX Project

HPX-Favicon-Full-Blue.png

The HPX Project has released V2.0.0 RC1 of HPX -- A C++ Standard library for Concurrency and Parallelism.

HPX is a general-purpose parallel C++ runtime system designed for applications of any scale. It implements the related C++23 Standard facilities in full and offers the only widely available open-source implementation of C++17, C++20, and C++23 parallel algorithms - including a complete set of parallel range-based algorithms and the full integration of the algorithms with the upcoming sender and receivers interfaces.

Beyond the standard, HPX includes proposed features for upcoming C++ releases: much of the parallelism and concurrency capabilities expected in C++26, the C++ Concurrency TS, Parallelism TS V2, data-parallel algorithms, executors, senders and receivers, and more. It also extends C++ Standard APIs to distributed environments (such as compute clusters) and heterogeneous systems (such as GPUs).

HPX enables an asynchronous C++ programming model that improves parallel efficiency and reduces the complexity typically associated with concurrent applications. As a newly welcomed project of the High Performance Software Foundation, HPX now benefits from vendor-neutral governance and collaboration with a broader ecosystem of high-performance computing tools, strengthening the foundation for portable, production-ready HPC software across the industry.

HPX V2.0.0 is one of the largest releases in the project’s history, touching the language baseline, the execution model, the networking layer, the build system, and observability tooling. Roughly 680 pull requests and 120 closed issues went into this cycle since v1.11.0 (June 2025). This release represents a year of collaborative development by dozens of contributors worldwide. The updates are extensive - see the full release notes for details.

 

by Hartmut Kaiser at September 28, 2026 08:17 PM

Keep It Tight: Restrict Variadic Templates Using C++20 Concepts -- Andreas Fertig

temp_file_fertig1.pngC++20 Concepts offer a cleaner, more expressive way to place constraints on templates—and make those constraints visible to anyone using them. Here, we’ll look at how Concepts can ensure that every argument in a variadic template has the same data type.

Keep It Tight: Restrict Variadic Templates Using C++20 Concepts

by Andreas Fertig

From the article:

I previously wrote about C++20's Concepts. Today I would like to discuss another aspect of Concepts: how they help you to limit the data type of a variadic type-template parameter to a specific one for all datatypes in the set.

For reference, these are my previous posts about C++20 Concepts:

 

by Blog Staff at September 28, 2026 05:51 PM

The Daily WTF

It's All Part 2 of the Process

Our submitter Tim C. is back as his bureaucratic nightmare continues. Read Part 1 here.

After I'd thrown the WTF Exchange (WTFX) for a loop, they managed to eventually right the ship. But then I faced another hurdle: I had run out of disk space. The software was not live, we were still developing the customer-specific customisations, but I was a bit stuck without a few more gigabytes.

WD Blue Hard Disk Drive connected to the Acer Laptop via SATA to USB-C adapter

The exchange went something like this:

"Hey Margritte, I need more disk space."

"Oh dear, what's happening?"

"Nothing is happening. I'm just developing the software. I need more disk space, not much. Can you get me another 20Gb? Wait, make that 40Gb."

"We can't just get you more disk space. These things need to be planned!"

"I just need a tiny amount, really. No need for any meetings. Just tell your IT guys to give me another NFS drive or expand one of the existing ones."

"Tim, that's not how things work here. We need to discuss your needs and it's important to us to know what needs you might have in future."

"Um, okay ... ?"

"I'll try to call an urgent meeting."

"Really? For 40Gb?"

"Well, how do we know 40Gb is going to be enough?"

"Because it's double what I really think I need."

"Why on Earth didn't you tell us before that you needed this disk space?"

"I'm telling you now!"

"Why didn't you do projections months ago?"

"At no stage did anyone ask me how much disk space we need! We obviously need some disk space! I have literally never given anyone an estimate! We are not even at the point yet to even estimate how much we'll need on project go-live."

"Well, I'll try to get an urgent meeting going. But it won't be today."

So at lunchtime, I went to the local computer store and bought an external hard drive. I asked Margritte to give it to the IT guys to stick somewhere in their computer room, or at least somewhere on their network.

That just seemed to make things worse.

"We can't take this! We have procurement processes!"

"Take it! This is a freebie from me to you. It'll help unstick a blockage in the project."

"It's not our standard hardware vendor. God knows what stuff is on it. We can't take the risk."

"I have literally not opened the plastic sealed wrapper on the outside of the box."

"Yes, but you could have re-sealed it. When we go via our trusted hardware partners we don't have to worry about things like that."

"You realise I'm making software every day which is running in the heart of your systems?! I work on this laptop here, and at the hotel, creating software, both C++ source code and Windows executables, that run inside your systems!"

"But it's not in the asset register. We need to record the warranty details every time we install hardware. What happens if it fails after you've left?"

"Well, how about we just agree I'll take it with me when I go?"

"Okay, I'll see if I can make the meeting happen tomorrow. To get you more disk space. Using our preferred hardware. Not that ... thing." (Said with disgust.)

Well, I finally got my disk space ... after a couple of days.

I was shocked to learn months later what a small proportion of the overall project budget our company earned. What seemed like an enormous multi-million-dollar contract to us was dwarfed by what WTFX spent on ex-pat "Anderson Androids", all immaculately groomed with expensive suits, who spent weeks twiddling their thumbs in expensive hotel rooms waiting for us to finish our software development, because they couldn't start until we had finished.

So sayeth the Gantt chart! Amen.

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

by Ellis Morning at September 28, 2026 06:30 AM