C++ 17 if statement gotchas

C++17 added a useful extension to the if-statement syntax, by making it possible to include initialisation inside the if-statement. This is called “if statement with initializer”. You can use it like this:

if (int spuds = getNumberOfSpuds()) {
    bakeSpuds(spuds);
}

Providing spuds != 0 it will obligingly bake them for us (in fact, it will even bake negative spuds… very handy in the current financial climate). Better yet, you can also add a condition, like this:

if (int spuds = getNumberOfSpuds(); spuds > 10) {
    std::cout << "we have plenty of spuds" << std::endl;
} 

This is often used to check pointers before dereferencing them:

if (auto* car = getCar()) {
    car->setHandbrake(true);
    car->setSteeringAngle(70.f);
}

Obviously these are very useful features, as it brings the variable instantiation into the scope of the if-statement and makes for neater code. We love it and use it a lot!

Unfortunately, this also seems to have led to a common misconception in how the condition can be used. In working on some fairly large C++ projects, we found quite a few instances of this type of code:

if (auto* car = getCar(); car->hasWheels()) {
    // DANGER: if car is nullptr, will dereference nullptr
}

The intent of this code is obvious: the developer clearly expected it to only execute the condition if car != nullptr. Essentially, they expected it to check that car != nullptr, then execute the condition, and only enter the if-statement if car is valid, and the car has wheels. However, it doesn’t work like that. It will always execute the condition and will dereference the car pointer, regardless of whether it is nullptr or not, so this code is quite likely to crash.

Usually this is fairly easily fixed by doing something like this:

if (auto* car = getCar(); car && car->hasWheels()) {
    std::cout << "we have a car, and it has wheels" << std::endl;
}

But the really nasty thing about buggy code like this is that it can often appear to work fine, until one day it blows up. This can lead to really nasty intermittent bugs, which are exceedingly hard to debug. Worse still, static code analysis tools might not spot this issue, and we had obviously missed some of these in code reviews also. If you suspect bugs like this are present, it’s also quite hard to grep your code base to find them. For example: searching for lines containing “if” and a semicolon will bring up a huge number of hits, which have to be searched manually. This makes it especially important not to introduce them in the first place 🙂

Here’s an example of some such code which appears to work (at least, it doesn’t crash), but is obviously not correct:

struct Car {
    bool hasWheels() {
        return true;
    }
};

Car* nullCar = nullptr;

if (auto* car = nullCar) {
    std::cout << "we have a car" << std::endl;
}

if (auto* car = nullCar; car->hasWheels()) {
    std::cout << "car has wheels" << std::endl;
    // Spoiler: this may be a lie
}

If you run this, it won’t output “we have a car”, but it probably will output “car has wheels”, even though car is nullptr. It does that because hasWheels is just returning a constant value, so the compiler doesn’t actually need to use our pointer. Although this is a somewhat contrived example (because our function could have been static, and we are using raw pointers etc), I hope it illustrates the point: that just because code appears to work when you test it, that doesn’t necessarily prove the code is correct.

Another misconception I’ve seen in practice is when people put initialisation in both the initialisation and condition, assuming that the compiler will check both conditions (it doesn’t):

if (auto* foo = getFoo(); auto* bar = getBar()) {
    // DANGER: if foo == nullptr and bar != nullptr
}

It will enter the if statement if bar != nullptr, even if foo == nullptr. For example, this code would result in a nullptr dereference, because it only cares whether the condition on the right hand side is true, and doesn’t care whether car is nullptr or not:

if (auto* car = nullptr; auto* driver = new Driver) {
    // DANGER: if car == nullptr, it will dereference the nullptr
    car->setDriver(driver);
}

It’s worth saying that this code wasn’t introduced by inexperienced C++ developers. In fact, some of it was written by very capable, experienced and knowledgeable C++ developers, some with many years of experience. It just goes to show how easy it is to slip up and introduce this kind of bug. I suspect this is a fairly common issue, and something that it is useful to be aware of.

Finally, if you want to search for this kind of issue in a large code base, it is somewhat possible by using regular expressions. For example, in Visual Studio’s “Find in Files” option, you can select “Use regular expressions”. To find lines that contain both “if” and a semicolon you can do something like this:

if.*;

This expression should find lines that contain “if” and a semicolon, but the semicolon can’t be at the end of the line:

\bif\b.*;(?!\s*$)

Don’t ask me about regular expressions, because I am no expert – just sharing one that worked for me 🙂

Either way, this will bring up a fairly long list of search results that you will have to sift through manually. All the more reason to take care not to introduce them in the first place…

Names in Scrabble

It’s obvious that a lot of names are also going to be valid words in Scrabble (Bob, Peter etc) and this made me wonder just how many there are…

Now, Scrabble has a ridiculously large dictionary, allowing all sorts of silly words that are frowned upon in our house 🙂 For example, there are apparently 124 playable two letter words (!) and, ridiculously, you can play Aargh, Aarrgh and even Aarrghh (!) Well, if you don’t believe me, you can check here.

I’m no authority, and there are several dictionaries including OSPD and SOWPODS, no doubt with differences between them. They are regularly revised to remove hate speech and, no doubt, so they can add some even more ridiculous words.

Anyway, I digress. After some tinkering around, I was able to intersect a list of names with a list of Scrabble words, to arrive at a total of… 1244 names. There’s a good chance yours will be in there 🙂

US words in Wordle’s dictionary

I enjoy playing Wordle over breakfast every day. It’s a wonderful little game, but the US spellings sometimes cause me some pain!

This made me wonder how many US words were in its dictionary. I had a look at the JavaScript source and found it uses a dictionary of 2315 words. That’s a lot to look through manually, so I ran it through a spell checker (MS Word UK English) and found the following 21 words:

apneafecalmoldy
arborfetalrumor
ardorfibersavor
armorfurortumor
boneyhonorvalor
colorhumorvigor
favorlaborwooly

It would be easy enough to substitute a different dictionary of course (and I suspect someone probably already has).

Microsoft really don’t want people to buy Visual Studio 2022 standalone…

I’ve been a fairly happy user of Visual Studio over the years. For all it’s faults, I’d probably even go so far as to say it’s probably the best Microsoft product I’ve ever used – including their OS! But with 2022, we are not off to an auspicious start…

Typically, I’ve always bought the next major release as a standalone version (2013, 2017, 2019 etc) and activated with a Product Key. When VS 2022 came out, I was pretty excited and naturally assumed I could just buy a standalone copy again…

How wrong I was!

The whole sorry saga started back in November 2021 when we contacted one of our usual resellers and asked them for a quote. Initially there was some confusion because it only seemed possible to get the subscription version at the time but, after a lot of back and forth with the reseller, we eventually got a quote for the standalone version late in December. The ordering slipped into the New Year due to holidays and issues with the reseller.

When it came time to order, the reseller sent us a link to some videos explaining how to use “Microsoft Cloud Services”. I was a bit perplexed to find that we needed to watch 3 videos before we could order the software, but they assured me they were very short videos!

So, I got a cup of tea and sat down to watch the videos on “Setting up a new online services tenant” then “How to align an existing online services tenant” then “How to purchase online services” without any real idea what an “online services tenant” was, or why I needed one to just install Visual Studio. Then I thought… what the hell, why is this so complicated? Can’t I just buy this from the Microsoft Store?

So, after some digging, I found this link on the Microsoft Store, so I went ahead and added 10 copies to my basket. Job done! …or so I thought.

The Microsoft Store sent me an e-mail saying thank you for your order then, a few minutes later, another e-mail saying it had been cancelled! What?

So I tried again. This time of course, my bank flagged it as card fraud, having seen two big transactions with the same supplier. So I had to call them and get the card unblocked.

Then I tried again – third time lucky as they say! This time it seemed to go through OK. I got another order confirmation and, eventually, received an e-mail with an “Install” link for the software. However, this “Install” link just took me to the order page on Microsoft Store, with no way to download the software, no way to obtain the Product Keys and no way to activate it.

Two of us then spent 6 days on the ‘phone to Microsoft. We tried calling the Microsoft Store support, exploring every department available from their ‘phone menu. Everyone we spoke to was unable to help, and either put us on hold, redirected us to another department, or opened a ticket, only to close it later with a message to call the same number we had already tried 50+ times before. In many cases, the departments we were connected to were closed, and they simply disconnect you!

Although polite, literally nobody we spoke to at Microsoft seemed able to help us, they just bounced us around from one department to another.

We tried online chats, e-mails and creating support cases with various Microsoft teams, all to no avail. In the end, over a week later, we resorted to cancelling the order and asked them for a refund.

Now I am waiting for a refund to my credit card, which can apparently take 5-10 days.

I have since spoken to Microsoft Store support again, and they have suggested ordering 10 copies as 10 individual orders, rather than as a single order!

So, I have been trying to buy this software since November, and still don’t have it. It’s the most incredibly frustrating experience. I can’t think of any other business that we work with who could get away with this kind of service, it really is something to behold!

Sourdough Starter meets… 3D printer!?

This idea is either genius…. or maybe I’ve finally lost my marbles? I’ve been using a “zero discard” method for my Sourdough starter, where you just pile some flour on the starter and leave it in the fridge (for days at a time, without feeding it). Then, when I want to use it, I just add water and leave it for a few hours to ferment. There’s only so many sourdough discard recipes 2 people can eat, and I can’t bear to throw it away, so this “zero discard” method is a good compromise (I am no expert on Sourdough, still experimenting…)

Anyway, it was a cold morning, I’d just taken the glass jar out of the fridge, added cold filtered water and wanted to get this thing moving quickly, so I thought… why not put it on my 3D printer’s heated bed, and set the temperature to something like 20ÂșC – 30ÂșC to get the party started!

Glass jars aren’t very thermally conductive, so I set the bed to
30ÂșC for an hour or so then, when the jar got up to a balmy 24ÂșC, reduced the bed temperature to 25ÂșC and left it until doubled in size. It works a treat! Got a nice bubbly, active starter – ready to rumble!

My Warning Stickers have arrived…

AvE does a nice line in warning stickers for machine tools. I was about to order some (probably still will) then realised they were going to take 4 weeks to arrive. In this age of instant gratification, I can’t wait so long… so I cracked open Inkscape and set about making some of my own. They arrived in a few days, and I’m really pleased with the result!

Warning Sticker: Achtung! Nicht Gerfinger Poken

Few things more exciting than opening a pack of fresh stickers! One is on my garden shredder, and another is going on my Lathe…

The minimum order means that I now have 50 of these, so I decided to take a punt by listing them here on Etsy.

More Windows 10 Weirdness

Since upgrading to Windows 10, I’m still having some weird issues… one thing that particularly annoyed me was the long delays when creating and renaming folders. After renaming a folder, Explorer would sometimes take about 10 seconds to respond. The fix for this issue was:

  1. In Windows Explorer, select the View menu.
  2. Click the Options button on the right hand side (not the drop down).
  3. On the General tab, under Privacy, untick both of the “Show recently…” and “Show frequently…” Quick access options as pictured below.

This fixed the slow renaming issue. The weird thing is, I’m pretty sure that I disabled these options before and they seem to have enabled themselves again?!

I’ve also got another really strange problem I can’t understand. Occasionally, I’ll boot into Windows and some of the apps won’t start – they just freeze up or hang on the splash screen. For example: Chrome, Calc, Outlook and nslookup (on the console) freeze and have to be force closed but, weirdly, others like Notepad and Excel just start fine, and ping and tracert both work. Multiple restarts don’t cure it.

Purely by chance, I found a way to fix this by rebooting the PC into Ubuntu Linux (it’s dual boot), shutting Linux down and rebooting into Windows 10. Simply restarting Windows isn’t enough, I have to actually shut down, log into Linux, then restart into Windows 10. I cannot understand how/why this fixes it…

UPDATE: I eventually discovered that holding SHIFT when shutting down Windows 10 makes it do a full shutdown, and a clean restart then cures the problem. This still happens to me occasionally… irritating.

TB6560 Stepper Motor Driver versus GRBL

For a while now I’ve had an old TB6560 Stepper Motor Driver board kicking around, which never really saw much use. I used to drive it from a PC parallel port (remember those?) with a very big, ugly old desktop PC running LinuxCNC. Because of the size, this was pretty inconvenient. Recently, I decided to resurrect it and try to drive it from an Arduino Uno with GRBL. It took some time to find the pinout online, particularly since there are several variants of this board with completely different pinouts, so I decided to make notes here…

This manual appears to correspond to my 3 axis board: (TB6560 3 Axis Manual) and here’s the pinout that I’m currently using successfully:

LPT1 PinLPT1 FunctionArduino PinGRBL Function
1X Step2Step Pulse X-Axis
2Y Enable8Stepper Enable
3Y Direction6Direction Y-Axis
4Z Direction7Direction Z-Axis
5Z Step4Step Pulse Z-Axis
6Z Enable8Stepper Enable
7X Direction5Direction X-Axis
8Y Step3Step Pulse Y-Axis
9Spindle Motor12Spindle Enable
14X Enable8Stepper Enable
25GNDGNDGND

This works but these blue TB6560 boards are absolute junk and have numerous well documented design flaws (e.g. skipping steps) which require DIY modifications to fix, so if you are considering buying one… don’t. There are plenty of better options available!

First experiences of Windows 10

I finally conceded to upgrade from Windows 7 to Windows 10 (Dell Precision M4700 Laptop) and… it’s not terrible, but I’ve had a few issues:

  • CDRW drive vanished. Fortunately restored by downloading drivers from Dell.
  • SD card reader vanished, required new Dell drivers and manually enabling some devices in device manager. I’ve still not got to the bottom of this one: every time I need to use my SD card, I have to open Device Manager and manually enable “Intel(R) 7 Series/C216 Chipset Family PCI Express Root Port 8 – 1E1E”. Still a major annoyance!
  • Takes an inexplicably long time to shut down, with a black screen. However, this seems to have to improved since a recent Windows update.
  • PDF files are associated with Edge by default. Which is odd, given that Edge seems incapable of opening PDF files. Fortunately, it is easy to change the file associations to fix this. Why on earth does it do this?
  • OpenGL quad-buffer frame sequential stereo no longer works properly (NVIDIA Quadro K2000M / 368.86 drivers). Either it displays the left stereo channel only, or works but with terrible performance (1 fps). Workaround: using the “Virtalis applications” profile seems to fix this (but restricts the 3D settings available). Solution: this one finally seems to have been resolved by Windows updates, and currently working OK on 369.09 drivers.
  • OpenGL stereo also causes issues with double images on the lock screen (below), and remnants of the lock screen are visible when returning to the desktop.quad_buffer_lockscreenThere is a temporary workaround: starting a stereo application and exiting it again temporarily fixes the desktop flicker, until the PC is locked again, at which point the problem returns. The only way to fix it otherwise is a reboot. Solution: this now seems resolved on 369.09 drivers.
  • When OpenGL stereo is enabled (on NVIDIA card/driver above), the display brightness increases to maximum, and it is not restored when the stereo application exits. Afterwards, the brightness controls in Windows no longer seem to work. Workaround: using the “Virtalis applications” profile seems to fix this. Solution: this one was eventually resolved by Windows Updates and/or 369.09 drivers.
  • The sound sometimes randomly stops working. Uninstalling and reinstalling audio drivers and fiddling with settings doesn’t seem to fix it. Then mysteriously, just after I’ve given up, it starts working again all by itself… spooky.
  • Windows Explorer often seems to respond really slowly and displays a blank page for a few seconds when initially browsing the local hard drives (which are both SSDs!) Solution: I disabled “Quick access” under: Quick access.. Options… General… Open File Explorer to: “This PC” (instead of “Quick access”). This eliminated the problem.
  • Recently (after an automatic update) every time I log into windows, I can briefly see a progress bar showing two files relating to the touch pad drivers being deleted (!) Still haven’t got to bottom of this issue.

In the interests of balance, some positive things…

  • The “Movies & TV” video player is much smoother at seeking in video.
  • The notification sounds remind me of Zelda / Wind Waker… which is cool.