In my previous post , I mentioned that I found a number of oddities when digging through the details of various Atari 8-bit file systems. I read through the specifications I could find online, and ran the actual code in emulators to verify and discover details when the specifications were unclear or incorrect. There were some surprising finds. I looked at: Atari DOS 1.0 Atari DOS 2.0s Atari DOS…
I got my start with computers as a kid with an Atari 800 way back when. When I'm feeling nostalgic, I still enjoy pulling it out and playing with it. These days, I'm more likely to pull out an emulator than the real thing, as they're now so precise that it's very difficult to find a difference, and it eliminates all the hassles involved with disks that were slow and may have failed with age. That…
I have a number of different devices and services running on my home network with web interfaces, and I would like to be able to access them all from anywhere. Some of these are smart devices, some are software packages, but it doesn't really matter. I want to be able to access them all by connecting to a web page on the server running on my firewall (or wherever port 443 is forwarded). To start…
I have a fairly complicated home network setup, which should come as a surprise to absolutely nobody. I recently dealt with an issue that had been bugging me for ages, but first some background. I want to be able to connect to my home systems from pretty much anywhere, and ssh is the obvious tool for that. Occasionally I've been somewhere where they've blocked outgoing connections to port 22 (the…
Most programmers are familiar with the "modulus" operator, which is the percent symbol in the language C and many other programming languages that have followed. Anyone who remembers learning division in elementary school will recall that when you divide a number, say 21 by a smaller number, say 5, you get a whole number part, 4 in this case, but there's a little left over. Later in arithmetic,…
I was discussing my day at work with my family, and I had spent much of the day resolving conflicts after doing a merge of two divergent branches. Of course, neither my wife nor my son understood what I was talking about, so I came up with a very simple analogy to explain what I was doing. Imagine a teacher wrote out a plot outline for a book, and then assigned each student to write one chapter.…
I have a new laptop with a 4K display. This is double the resolution in each direction of a typical laptop, but with the same physical dimensions. That means each pixel takes up a quarter of the space of a single pixel on a traditional display. By default, many things will run using the same number of pixels as on a smaller display, resulting in text too tiny to read. Making the problem more…
For the most part, C++ is a superset of C. You can write C code, rename the file with a .cpp extension, and the compiler will compile it in C++ mode, generating essentially the same code. In fact, the very first C++ compilers were actually C compilers with extra pre-processing. But there are some subtle differences, and I recently ran into one that has some important implications. In C, string…
From time to time I realize just how slow and outdated my computer is. Usually that's long after the corporate policy says I can order a new one, and this time was no different. The engineering laptop is a Dell (no surprise if you know where I work), and the default model is the Precision 5510. New computers always come with Windows installed, so my first task is to install Linux. I figured other…
For my final segment on the use of gotos, let us not forget one important hidden goto. The switch statement is essentially a goto with a variable label. This means that the if(0) trick can apply here, too. Before I get into the meat, I want to point out that many of the examples in this section aren't great code. In most cases the best way is to find a more traditional solution. Unlike the…
One other place where goto can be useful is in implementing tail recursion. As you should recall, tail recursion is when a function returns with a call to itself. For example: foo( int a) { ... if ( recurse ) { return (foo(a +1 )); // tail recursion } } Most compilers will optimize that into a goto to the top of the function. However, in some cases the compiler will fail you, and you have a…
Another time I often find use for a goto is in a for loop that is scanning an array to find a match. If a match is found, a break terminates the loop. See the standard version of this below. It repeats the condition check for the loop to see if the loop terminated early. The other option would be to use a flag to indicate if a match was found. This requires initializing the variable and then…
If you're in a nested loop in C code, and you want to issue a break or continue statement, but want it to apply to the outer loop, you're going to have some awkward code. for (j =0 ;i < j_end; ++ j) { for (i =0 ;i < end; ++ i) { ... if (condition) next_j; // break then continue? ... } ... } Implementing that 'next_j' statement could be done with setting a flag, issuing a break, and then checking…
The most obvious use of a goto statement in C is for exception handling. Many people before have noted that this is one good use of gotos. It's not unusual to have a function with a number of checks for errors. When an error is encountered, the function must release locks and free memory acquired and allocated at the start of the function before returning an error to the caller. The simple way to…
Hopefully you've heard of the famous letter by Edsger Dykstra, "Go To Statement Considered Harmful." This was one of the most influential letters ever written in Computer Science, published in Communications of the ACM in March, 1968. This letter effectively defined structured programming for generations of coders. It has been taken as gospel and taught in so many programming classes that most…
This post is mostly for my own use, but I figure some others might like it, too. You may have noticed that I have some nice code blocks in some of my posts. I may start with something like: function(args) { if ( maybe ) do_something(); } (I set the font to offset the above code using the font-selector make it stand out a bit.) How to I get those nice looking blocks? To start, I use a site to…
Many of my friends have heard me complain (OK, rant) about DRM. DRM officially stands for "digital rights management," but I prefer "digital restrictions management." The most common use of DRM is for video like Blu Ray discs and Netflix. DRM software enforces the restrictions imposed by the seller. You only get to use the media in the way they intended, no matter how much money you spent to buy…
Every so often, I find that I need to script some network connection. For interactive jobs, the standard answer is to use 'telnet' with 'expect' to achieve this. Unfortunately, expect is often a major pain to work with. The obvious modern solution would be to use Python, but I haven't learned that yet. What I do know is Bash, and wouldn't it be cool to do this entirely in Bash? So to prove that…
On May 11, 2000, I ordered our first DVR. It was a ReplayTV 2020, capable of recording 20 hours of TV on its 20GB hard drive. We had previously used a VCR for recording several shows, but the DVR experience was so much better that we never even got around to watching some shows that we had previously recorded on VHS. Five years later, we replaced the ReplayTV with MythTV. I've refreshed the…
This is a fun little tidbit. Assembly language is, obviously, not portable. If you use inline assembly code in a C program, you won't expect it to run on multiple processors without special handling for each one. Well, there's an exception to that. First, the trivial exception: __asm__( "" ); That's valid code (assuming the gcc compiler, as I will throughout this discussion). But it doesn't do…
One of the most powerful communications tools available is ssh. Pretty much the only version on Linux is OpenSSH, and most of the versions I've come across on other platforms are derived from it. I assume you know that, and I assume you also know that the best way to use it is with pre-shared keys so that you don't have to worry about passwords. Unfortunately, that isn't always an option. Recently…
Earlier this year, I was given a puzzle as a gift. It's a simple frame with Tetris-like blocks of different shapes, and the object is to get all nine blocks into the frame. Making it more difficult, there will be leftover empty squares throughout the puzzle. I played around with it for a while, and it wasn't too difficult to get to within one square of completing it, but I was probably nowhere…
When writing a program, everyone encounters bugs. Usually the first thing you will try to do is fix the bugs. Don't do that. Fixing bugs should be the last thing you do. Yes, you will need to fix them, but it should, quite literally, be the last thing you do. Fixing a bug is like looking for your lost car keys. You always find them in the last place you look. Why? Well, of course, because you stop…
If you've played with networking at all, you should be familiar with 127.0.0.1 being localhost. If you look closely at the network settings, you'll see that this is on a loopback device, and it's configured as a /8 network, not just that one IP address. That means any IP address in the range of 127.0.0.0 through 127.255.255.255 goes to the loopback device. Typically your hosts file only uses one…
I've been developing software for over three decades. Half of that professionally. The rest as a student or as a hobby. Over the years, I've noticed many things that have been quite valuable for my career, but generally not things taught as part of a standard curriculum. The purpose of this blog is to collect various bits of wisdom that will hopefully be of value to others in the same field,…