Friday, November 21, 2025

Windows 10 SDK 10.0.20348.0 is gone

I was caught by surprise today after updating Visual Studio 2022 to version 17.14.11. All my projects failed to compile, because the SDK files disappeared. I first thought something broke with VS Code support, but then I saw that Visual Studio itself had the same problem.

Turns out the Windows SDK I was using – 10.0.20348.0 – was simply deprecated and removed in this update, according to here, and the release note itself. Indeed, Visual Studio Installer won’t show it anymore.

Apparently, now I’ll have to install a Windows 11 SDK, even if I’m running Windows 10. I hope this doesn’t break my stuff.

Wednesday, November 5, 2025

Non-movable and non-copyable C++20 classes

On my fantastic journey implementing WinLamb v2, I’m diving deep into C++20, grasping a lot of concepts I never understood before, and having a lot of fun along the way.

One of the things that I implemented was the idea of non-copyable and non-movable classes, at first, using macros. This felt inelegant, so I implemented P2895 paper with utility classes. It ultimately failed with the nested ListView classes, so I discarded the idea too.

My final solution was to = delete move constructor, which will prevent all copy and move. The hard rules are not particularly easy to memorize, so I’ll let them here for further reference:

  1. The two copy operations are independent. Declaring copy constructor does not prevent compiler to generate copy assignment and vice versa. (Same as in C++98.)
  2. Move operations are not independent. Declaring either one of them prevents the compiler to generate the other. (Different from copy operations.)
  3. If any of the copy operations is declared, then none of the move operations will be generated.
  4. If any of the move operations is declared, then none of the copy operations will be generated.
  5. If a destructor is declared, then none of the move operations will be generated. Copy operations are still generated for reverse compatibility with C++98.
  6. Default constructor generated only when no constructor is declared. (Same as in C++98.)

Example:

class Foo {
private:
	Foo(Foo&&) = delete; // non-copyable, non-movable
};