Project: Bed Lights

A few months ago, my wife and I were in the market for a new mattress. We popped into a local mattress store and spent the better part of the afternoon stretching out on almost everything they had. Before we left, we tried a really nice, we’ll-probably-never-afford kind of bed. It had controls for firmness and head and foot elevation. There were temperature and massage controls. Memory foam. There were even ground lights. That’s right. Ground lights! What a brilliant idea?!

We left the store empty handed. But the thought of those ground lights stuck with me. How fantastic it would be to have such a thing for a midnight pee run. Something bright enough to help you find your way, but dim enough as to not wake the blanket-stealing snore-machine sleeping next to you (To My Wife: Baby, your snores are like lullabies. Truly.). Of all of the things that fancy bed had, it was the ground lights I wanted the most.

So I decided to make my own, but with a couple of enhancements. I definitely wanted motion activated lights. Who wants to bother feeling around for a on/off button at 3 AM? I also wanted an adjustable brightness control. It’s hard to gauge how bright is too bright until you actually start to use it. I knew it would need to be tuned.

This blog describes my little bed-lights project. I’ll detail everything you need to know to build your own. Note that if you attempt this project, some of your parts will probably vary. As a result, you’ll need to adjust values of other components accordingly. I’ll try to help you out where I can.

[Disclaimer: If you choose to tackle this project, I take no responsibility for any bad things that might happen. If you wire something up wrong or take a shortcut that results in a fire, that’s not my fault. As the folks keen on legalese say, this blog is for informational purposes only.]

Parts List

Here is the parts list for the project

Component Qty Approx. Price
½” 10’ PVC Pipe (Home Depot or Lowes) 2 $5
½” PVC End Caps (Home Depot or Lowes) 4 $1.50
LED Holders, 5mm 12 $1.50
2.1mm Female DC Power Barrel Connectors, Panel Mount 5 $15.00
2.1mm Male DC Power Connectors 4 $6.50
20 AWG wire 1 Spool, 100ft. $10.00
20 AWG 25′ Hook-Up Wire(For convenience in building power cables. Not entirely necessary. You could just use wire from the previous item. You’ll definitely have plenty of leftover if you buy 100′. ) 1 $4.30
Rustoleum Flat, Black Spray Paint 1 $6.00
Heat Shrink Tubing 1 Pack (Won’t Use It All) $7.00
9V 2.1mm wall wart, at least 500mA 1 $11.00
500mA Fuse 1 $2.20
Fuse Holder 1 $1.00
White LEDs, 5mm 3Vf (Mine came from EBay in a 300pcs assortment pack) 12 $0.25
330 Ohm Resistors 14 $1.40
2.2k Ohm Resistors (Specific to the current needs of my light rails – see notes below on how you might need a different value) 2 $0.20
2N3904 Transistors (NPN) 2 $0.50
1N4001 Diodes 2 $0.50
1 M Ohm Potentiometer 1 $5.00
Adafruit PIR Sensor 2 $20.00
Perfboard 1 $3.00
Enclosure for Controller 1 $6.00
Enclosures for PIRs and lids 2 $3.50
Velcro Straps 1 Pack $4
Velcro Tape 1 Pack $5

Total Project Cost: ~$120.00

Granted, this is just an estimate. All of the passive components I had laying around. You might find much of what you need by poaching old busted electronics.

Overview

There are 3 basic components to the bed lights. The first, and most obvious one, is the pair of light rails – one for either side of the bed. The second component is the motion sensor (PIR). There are two of these as well. The third component is the controller box. This is where power gets distributed, motion sensor input is handled, and lights get switched on. It’s also where the control knob for the brightness control lives. The basic configuration is like so.

Something that’s not obvious from the sketch is that each PIR controls both light rails. If one of the PIRs is triggered, both rails light up. And if both PIRs are triggered at the same time, both rails still light up.

Building the Light Rails

The first step to building the light rails is cutting the PVC pipe down to size. The ½” pipe that I bought came in 10 ft. lengths. That’s way too long for my bed. So, using a hacksaw, I cut both pieces down to 7ft.

Next, I drilled 6 evenly spaced holes for the LED holders in each pipe. The trick here is to initially start with a small drill bit and then work up to larger ones, testing the LED holders as you go. It was important that the LED holder was able to pop in, feel somewhat snug, and then pop out easily again.

For each pipe, I planned to cap both ends. But in the cap for one end, I drilled a center hole large enough to accommodate one of the female 2.1mm barrel connectors. This is where power will be supplied to the rail. Actually mounting the connectors and attaching the end caps should happen last, after the rail is wired up and ready to report for duty.

At this point, I painted both the pipes and the end caps by applying a couple of coats of flat black Rustoleum spray paint.

Next up – the wiring.

Each LED on the rail has an associated 330 ohm resistor and each LED/resistor combination is wired in parallel. If one LED dies, the rest will continue to light up. As shown in the photo below, I merely soldered a resistor to one of the legs of the LED and then connected wire as appropriate (Note: The PVC in the photo below is unpainted. This photo was taken as I was still experimenting.) I then tidied things up with heat shrink tubing.

I should point out that it’s much easier to snake the wire through the pipe a segment at a time between holes and wire up the LEDs in-place, than it is to try to wire up everything outside of the PVC pipe and then to try to snake the whole thing through the PVC in one fell swoop. I learned this quickly. Trying to assemble everything outside of the PVC pipe just leads to headaches as you try to fish the LEDs/resistors out through the holes. It’s time consuming and not worth it.

It’s important to make sure the LEDs are wired up properly. They have polarity. And because we’re wiring things up in parallel, 5 of the 6 LED combinations will be connected to 4 wires. If you’re having trouble visualizing this, here’s a diagram to help you out. 5 of the 6 LED/resistor pairs have an incoming positive connection as well as an outgoing positive connection. The same is true of the negative connections. Only the last LED/resistor pair has single connections for the positive and negative terminals.

After the LEDs were wired up, I tested each rail with a nine volt battery to ensure everything lit up. I then popped the LEDs in their holders, put a dab of superglue on each holder, and pushed everything down in their holes. Some LED/resistors didn’t appreciate being pushed down into tight quarters, so I tested the LEDs again as I went along to ensure I didn’t break something or short a connection.

Next up, the DC power connectors. I soldered the leads appropriately to the power connectors, being careful to get the polarity right. A multimeter is handy for that. If you’re uncertain what’s negative and what’s positive, plug in your power supply directly to the jack and find out. If you don’t have a multimeter (God, help you), you can always test using another LED resistor pair separate from your light rails. If everything is connected up properly, the LED should light right up. If it’s backwards, the LED will go up in smoke or won’t light at all.

With the jacks wired up, I mounted them into the PVC end caps and superglued all caps to the pipes. The light rails were finished.

Building the Controller

As mentioned before, the controller serves three purposes – 1) Distribute power to all the other components. 2) Switch on the lights when the motion sensors are triggered. And 3) provide a mechanism that allows me to adjust the brightness of the light rails. All three of these goals are accomplished in the following circuit


Click to Enlarge

How It Works

Power is distributed to the light rails and PIRs after passing through the 500mA fuse. The fuse is there just in case we get a short anywhere. It would probably be better to go with a fuse closer to the current rating of the actual circuit. 500mA is what I had on hand.

The negative sides of the light rails are connected to the collector of an NPN transistor. In my configuration, the transistor works like a switch. When the appropriate voltage is applied to the transistor’s base, current will be allowed to flow from the collector, through the emitter, and on to ground. This will allow the light rails to light up.

I should note that transistors could have been replaced with simple relays. If you prefer to go that route, you won’t need the resistors attached the the transistors’ bases. However, relays are clicky. And this is a bed/sleep related application. The sound of relays might be a little annoying in the middle of the night.

Determining the resistor values for the transistors’ bases depends entirely on the power needs of your light rails. On paper, each rail draws 109mA each at 9V. The magic formula for determining the base resistor value is:

R = switching_voltage * Hfe / (1.3 * load_current)

The switching voltage is the signal voltage from the PIRs (3.3v). I’ll have more to say about the PIRs shortly. I have to confess, the Hfe of a transistor is somewhat of a magic number to me. Technically, it’s the ratio of the load current to the base current. Given I didn’t know my base current, I wasn’t quite sure how to calculate this. Most folks on the Interwebs claim that 100 is a good number to use for the 2N3904. So that’s what I went with. Plugging the numbers into the formula gives us:

R = 3.3V * 100 / (1.3 * 0.109A)
R = Approx. 2329 Ohms

I didn’t have such a resistor in my Box-O-Electronic-Thingamabobs, so I went with a combination of a 2.2k Ohm and a 330 Ohm to get me close. Better to be over than under (I think).

The diodes in the circuit are used to protect the signal pins of the PIRs. These may not actually be needed. I’m not entirely sure. Without them, I worried that if one PIR goes high and the other is low, a voltage would be placed across the signal pin of the low PIR and damage it. Would this actually happen? No clue. But I decided to play it safe and add diodes to the mix. The diodes allow current to flow in only one direction – out through the transistor.

The 1M Ohm potentiometer is used to limit the current that can pass through the transistor’s base. This component allows the transistor to work like an amplifier as well as a switch. By decreasing the amount of current through the transistor’s base pin, we decrease the amount of current that can flow in from the light rails and out through the emitter. Turning the potentiometer clockwise increases the resistance on the transistor’s base. Increasing resistance lowers the current. And, voila, we have an adjustable dimmer.

Assembling the Controller

With regards to the circuit, I can’t really give much advice. Just follow the circuit shown above and arrange the components in a way that works for you. I used a perfboard without any traces. I connected components using a combination of jumper wires and solder bridges. None of the power connectors, nor the potentiometer were mounted directly to the perfboard. If I had a perfboard that was perfectly fitted for my enclosure I might have gone that route, but I didn’t. So those components were connected using wire.

As for the enclosure, I strongly recommend planning out the component positioning before going anywhere near it with a drill. It’s EXTREMELY frustrating to drill a bunch of holes only to discover that there’s not enough space inside the enclosure to fit everything safely. Space on the inside fills up quickly.

A fellow by the name of John Cooper has an excellent YouTube tutorial on using Sketchup to layout enclosures for guitar effects pedals. I do something similar for my enclosures using 3DS Max. I encourage you to check out John’s video, learn something new, and apply this practice to all of your enclosures. It’ll save you a world of pain.

I discuss the PIR sensors below. But I should mention here that I didn’t have any compatible connectors on hand that I could mount onto the enclosure. The PIRs require three pins – power, ground, and signal. All of my connectors are of the two wire variety. So I just drilled a couple of holes in the side of the enclosure for the PIR cables and soldered them directly onto the perfboard. As a result, the PIR cables are the only cables that aren’t detachable from the controller enclosure. I may fix this at a later time. Or I may not. It’s not that big of a deal.

Motion Sensors (PIRs)

The motion sensors I selected for this project are $10 PIR sensors from Adafruit. PIR sensors detect changes in infrared light. You can find them at just about any electronics outlet. The Adafruit version is interesting in that it has 2 adjustment pots – one for sensitivity and one for a time delay. Adafruit’s website recommends these things be powered at 5v, but claims that 9v is an acceptable upper limit. Since I’m running everything else off of 9v, that wins by default. There’s always a risk I’ll burn these things out quicker. Time will tell, I guess. If you’re following along with my project and you’d rather go with the suggested 5v, just create a voltage divider out of 2 resistors.

The sensitivity adjustment seems to correlate to range. The most sensitive setting comes in at around 20 ft.

The time delay adjustment affects how long the signal will remain high after the PIR has stopped detecting motion. I’ve adjusted both of mine to be around 15 seconds. By using two sensors (one for either side of the bed), this gives a person plenty of time to get from one side of the bed to the other and out of the room before the light rails shut off.

The Adafruit PIRs come with a 1ft long 3-wire 26 AWG cable attached to a 2510 Molex connector. 1 ft. is obviously not long enough, so I fashioned extension cables out of leftover wiring from the light rails and some heat shrink tubing. If you want to get fancy, find yourself some more 2510 Molex connectors for your controller enclosure so you can have detachable PIR cables. I didn’t have any available. As I said before, I just soldered the cables directly to the controller board. Not pretty, but it works.

The enclosures I used for the PIRs weren’t ideal, but they were the best I could find. Here’s a picture of what they look like.

With a stepper drill bit, I drilled holes in the front of the enclosure large enough to accommodate the PIR sensor. A used a dremel to carve out a hole in the back just big enough for the Molex connector. Once everything was connected, I taped the thing shut.

Light Rail Cables

The last thing you’ll need to construct is a set of power cables for the light rails. You might be able to find some long 2.1mm male/male cables online if you’d rather not fuss this step. But creating power cables for the light rails is probably the easiest part of the entire project.

For a single cable, all you need are 2 2.1mm male DC connectors and some 20 AWG wire. The connectors unscrew to reveal terminals for soldering. Make sure you wire one end of the cable up the same way as you do the other end (negative to negative, positive to positive).

Installation

Attaching the setup to the bed involved lots and lots of velcro. Both the controller and the light rails were attached with velcro straps. The motion sensors were attached to the footboards using velcro tape.

The light rails were angled such that the light pointed down and away from the bed. The PIRs were mounted near the headboard, but angled so they pointed towards the footboard and slightly out. Hopefully that shows in the photos below.

Conclusion

All in all, this is a pretty simple project. And a lot of fun. We’ve been using these bed lights for well over a week now. I think I can say this project has been a tremendous success. The brightness level took a little tuning. It’s amazing how bright light can seem once your eyes adjust to darkness. It took three nights of dimming the LEDs before I found a brightness level that didn’t wake one of us up. But I found it. No more feeling around for the cell phone to light my way to the bathroom in the “wee” hours (cue rimshot).

Something I hadn’t anticipated, but worth mentioning, is the psychological effect of having the lights switch on in the middle of the night when they shouldn’t have. Ghosts? Mice? Dust bunnies on the move? It stirs up anxiety, which doesn’t bode well for the sleep-deprived mind. Just be aware that if you’re sensitive to such things, you’ll probably need to adjust the sensitivity of the PIRs (glad we only taped those shut :-)).

Some specs you might find interesting. When idle (the light rails off), I measured the current draw at around .1mA. That’s barely anything. With the lights on at full brightness, the current draw is around 130mA. That’s almost half of my original full-on value for both rails. I’m sure there was a fudge factor in my transistor base calculation. The lights could have been a bit brighter. But that’s fine. Even at max power now, the light rails are too bright to be practical.

C++ Exceptions: The Good, The Bad, And The Ugly

Recently, a recording of Titus Winters’ presentation from CPPCon 2014 found its way around the office. In the video, Titus discusses style guides and coding conventions as they apply to Google’s C++ codebase. One of the contentious topics touched upon was the use of exceptions, which are apparently verboten at Google. That, of course, sparked a few questions from Titus’ audience and incited some debate within our own organization.

It’s interesting how polarized C++ developers are when it comes to the use of exceptions. It doesn’t matter if you talk to a junior developer or a 20 year veteran. You’ll almost always get a response that lies at one of two ends of the love/hate spectrum. At one end is “Exceptions are evil. Like, goto-evil, man. It’s chaos. Biggest wart in the C++ standard, bar none.” At the other end is “Dude, it’s 2015. WTF aren’t you using exceptions? They’re so chic, so modern. So much better than those geriatric return codes.” Of course, put a few beers in these folks and maybe some free food, and their postures will waver. Both parties eventually admit there’s some good and some bad when it comes to exceptions. As it turns out, the exception is a language feature that’s not as cut-and-dry/black-and-white/1-and-0 as we programmery folks care to admit.

For this blog entry, I thought it might be useful to take a step back and look at things from a 10,000 foot view (or 3,048 meters for my imperially challenged friends). Let’s spend some time picking apart the arguments for and against C++ exceptions. Even if we can’t arrive at some grand conclusion, it’ll at least allow us to appreciate the perspectives of our peers a little better. And who knows? Maybe we’ll find some middle ground.

So let’s start on a positive note. How about some pros?

The Pros:

Exceptions cannot be ignored.

In C, the convention for communicating errors is the much beloved error code. It’s succinct, there aren’t many surprises, and it gets the job done. None of us are new to error codes. We encounter them every day in system calls, standard library functions, third party libraries, and even in our own code.

The dirty truth is that in C, errors are ignored by default. A function caller is free to exercise their right to ignorance. As a result, “failable” function calls often go unchecked. And when unexpected failures occurs, one of three things typically happen:

  1. Nothing. The failure wasn’t fatal. The code continues to operate just fine.
  2. The code doesn’t crash, but the application starts to behave strangely and sometimes eventually crashes.
  3. Boom. The application crashes and burns immediately.

The same code path with the same unchecked failure may even exhibit a random selection of one of these three behaviors every time it’s executed.

In contrast, exceptions cannot be ignored. An uncaught exception does one thing – crashes the application. It forces you, as the developer, to make error handling a priority.

Exceptions can carry more information than return codes.

To make sense of an error code, you usually need to look it up. You might have to refer to another source file, the API docs, or a sticky notes in the guy’s cube next door. And even then, you might not be able to determine exactly what caused the error.

“File open failed.” – Ok. But what file? And why?

“Connection reset by peer.” – Which peer?

Maybe you don’t care about the specifics. But if you do and you’re not sure what exactly caused the problem, a bit of sleuthing my be required. That means more work on the error-handling side of the fence.

Ideally, you’d be able to capture more details on the error-causing side of the fence. Exceptions can help with this. In C++, anything copyable can be thrown. With a copyable user-defined type, you can capture as much context relating to an error as you’d like and communicate that to the caller just by throwing it.

Exceptions allow error-handling code to exist separately from the place in the code where the error was detected.

How many times have you seen code that looked similar to this?

bool success = doSomeWork();
if (!success)
{
    logError("Error Occurred");
    return;
}    
success = doMoreWork();
if (!success)
{
    logError("Error Occurred");
    return;
}    
success = doEvenMoreWork();
if (!success)
{
    logError("Error Occurred");
    return;
}
// etc. 
// etc.

This code snippet contains a lot of noise. And it’s a little repetitive in how the error is handled. What if we need to change our error handling behavior? We’ll need to visit each place where success equals false. How different might this look if we were using exceptions?

Let’s assume the functions doSomeWork(), doMoreWork(), and doEvenMoreWork() throw exceptions instead of returning a success value. Our code might then look like this…

try
{
    doSomeWork();
    doMoreWork();
    doEvenMoreWork();
}
catch (...) // Or some specific exception type.
{
    logError("Error occurred.");
    return;
}

The code footprint is smaller and we’ve concentrated our error-handling in one spot. In the normal, non-exceptional case, the code actually runs faster than the previous code snippet because it doesn’t have to constantly check return values.

Exceptions allow errors to propagate out of constructors.

Constructors don’t return anything. They can’t. The standard says so. So what happens if an error occurs during the execution of the constructor? How does client code know something went wrong?

There is, of course, a brute force way to accomplish this. You could include error flags in the class being constructed and set them/check them appropriately. This is a bit of work and it requires both the class and its client to have an agreed-upon contract for error checking. It works, but it’s not really ideal. It results in a bit of extra code and it’s easy to make mistakes.

A much easier way to communicate errors from the constructor is to throw an exception. It’s straightforward and doesn’t require the class implementer to pollute the class with error flags and error-related getters/setters.

That being said, throwing exceptions from constructors does have a gotcha. If an exception is thrown from a constructor, no instance of the class is created, and therefore no destructor will be called. Think about that statement for a second. What this means is that that if there were any resources (heap allocations, opened handles, etc.) acquired in the constructor prior to the exception being thrown, they may be leaked unless appropriate steps are taken.

Exceptions are better than setjmp/longjmp.

The setjmp/longjmp dynamic duo comes to us from C. They provide a mechanism for performing what is referred to as a non-local jump, (sometimes called a non-local goto). setjmp is called to mark a point on the stack where program execution should return and longjmp is used to jump back to that point. The way it works is that setjmp records the contents of the CPU registers, which includes the stack pointer. When longjmp is called later, those register values are restored and the code executes as if it had just returned from the call to setjmp.

What happens to all the stuff that was on the stack between the call to setjmp and longjmp? As you might expect, it’s all discarded. It’s as if that stuff never existed.

You might be saying to yourself, “This just sounds like stack unwinding.” It’s certainly a form it. But when C++ programmers thinks of stack unwinding, they imagine walking down the stack frame by frame and executing little bits of code along the way until their destination is reached. In traditional stack unwinding, destructors for stack-allocated objects get called and RAII objects get the opportunity to clean house. If we’re dealing with compilers with try-finally extensions (Visual Studio), even finally blocks get executed.

Unfortunately, that’s not the form of stack unwinding we’re dealing with when we work with setjmp/longjmp. longjmp literally jumps down the stack to the point recorded by setjmp in one fell swoop. It doesn’t do it frame-by-frame. It doesn’t call snippets of code along the way. It’s one second you’re here, the next second you’re there. Destructors for local variables don’t get called. RAII objects never do any cleanup. And finally blocks never get a chance to do their job.

And that’s why exceptions shine over the use of setjmp/longjmp. Exceptions allow for the form of stack unwinding that C++ developers are comfortable with. They can sleep easy at night knowing that local variables get destroyed as expected and destructors will execute even under the most exceptional of circumstances.

Exceptions are easier to propagate than return codes.

Conceptually, error code propagation seems like a no-brainer. Functions that call other “failable” functions check error codes, react appropriately, and propagate the error down the call stack if it’s appropriate. Pretty simple, eh? Not so quick. Checking error codes for function calls requires a certain amount of vigilance. It can be tedious. And, as shown in a previous pro, it results in a lot of extra, repetitive code. In practice, it’s not uncommon for many function calls go unchecked. It’s usually just the “important” ones that get all of the attention. And because errors are ignored by default in C, many errors tend to slip through the cracks. As functions call other functions that call other functions, this problem compounds and an application can miss out on opportunities to react.

As mentioned before, exceptions are propagated by default. There’s no way to accidentally ignore an exception without crashing your application. If you’re writing a function that calls another function that throws, and you wish the caller of your function to handle all the errors, there’s nothing you need to do. (Disclaimer: In some circumstances, it may be desireable to catch and rethrow the exception. So you may actually need to do something. But it really depends on the needs of your function. See the references at the end up the article for situations where this might be appropriate.)

And now for the glass-half-empty list.

The Cons:

Exceptions are more complex than error codes.

Something an error code has over an exception is simplicity. The concept is so easy to grasp someone completely new to coding can learn how to use and apply error codes almost immediately. The very first function any C/C++ developer writes is main(). And guess what? It returns an error code.

Exceptions aren’t as simple. Not only do you need to understand things like throw, try, catch, nothrow, and dynamic exception specifications (deprecated), but also an assortment of supporting functions and data types, such as std::exception, std::exception_ptr, std::rethrow_exception, std::nested_exception, std::rethrow_if_nested, etc.
There are also plenty of rules and best practices that must followed like…

“Don’t emit exceptions from destructors.”

“Constructors must clean up before throwing because a destructor will not be called.”

“Assign ownership of every resource immediately upon allocation to a named manager object that manages no other resources” (dubbed Dimov’s Rule by Jon Kalb)

etc.

It’s a lot to absorb. Really. And it can be intimidating to both new and seasoned C++ developers alike.

Writing exception-safe code is hard.

Even if you understand all of the exception-related concepts and jargon mentioned in the previous item, writing exception-safe code is still hard. As Scott Meyers says in “More Effective C++”, “Exception-safe programs are not created by accident.” Code absolutely must be designed with exceptions in mind. This includes the throwers, the catchers, and EVERYTHING in between.

Bad things can happen in functions that aren’t expecting to be short-circuited by an exception. That’s one of many reasons the introduction of exceptions to a legacy codebase that doesn’t already use exceptions is a very, very bad idea.

Exceptions make coder harder to read because it creates invisible exit points.

A function that returns an error cannot cause the calling function to prematurely return (we’ll ignore interrupts, abnormal program termination, and setjmp/longjmp for the moment). If a function decides to check the error code produced by another function and return based on some criteria, you’ll see that written down in the code. It’s explicit and not easy to hide.

The potential for a thrown exception can be subtle. If your function calls another function that throws, and your function doesn’t catch the exception, your function will stop executing. From a readability standpoint, this can be awful. It may not be obvious that any given block of code may be prematurely terminated, even if it’s completely designed with exceptions in mind.

Knowing what to catch can be tricky.

There are some languages that are aggressive about making sure you follow the contract when it comes to exceptions. Java, I’m talking about you. In Java, if your function throws an exception, it MUST have an exception specification that says so. (I’m strictly referring to checked exceptions here. Java also has unchecked exceptions. Those are harder to recover from and are exempt from the rules I’m discussing here.) If it doesn’t have an appropriate exception specification, you’ll get a compile time error. Also in Java, if your function calls another function that throws an exception, you MUST either catch the exception or have a compatible exception specification on your function. If you don’t, you’ll get a compile time error. The compiler holds your hand a bit here.

C++ doesn’t support such things. The compiler doesn’t care one way or the other if an exception is caught. It assumes, perhaps naively, that you know what you’re doing (also perhaps naively). C++ does have exception specifications. But historically, dynamic exception specifications like you see in Java never really helped us out in C++ land. They just muddied the waters. In C++, if a function doesn’t have an exception specification, it can throw anything it wants. On the other hand, if a function has a dynamic exception specification, it can only throw the types, or subtypes of the types, specified. Throwing anything else results in std::unexpected being called. Of course, this a runtime check, and it does nothing for us at compile time.

As you might expect, dynamic exception specifications fell out of favor in C++. They were so loathed that they were deprecated in C++11. All we’re left with in the C++11/14 era, is noexcept or nothing at all (which means anything can be thrown).

Another aspect of this “knowing what to catch can be tricky” thing is that there’s no universal base class. Sure, there’s std::exception. But that class was intended to be a base for exceptions thrown by the standard library. There’s nothing forcing you to use that for your own exception types. You can technically throw anything copyable in C++ – int, char *, std::vector, your own made-up type, etc.

So how do you do know what needs to be caught when you call another function? The compiler certainly won’t help you. Unfortunately, you must turn to documentation, comments in code, and in the worst case, wading through actual source code. Blech.

Exceptions incur a cost.

Nothing is free. When an exception occurs, there is a cost. Older compilers may impose some performance overhead when executing a block of code whether it throws or not. Modern compilers only incur a performance cost when the exception actually occurs. Exceptions should be rare. So if there’s no throw, there should be no performance penalty.

Even if there’s no performance hit, there will always be a size cost. When an exception occurs, the application needs to do more work to make the exception work than it would, say, a simple return statement. There’s more bookkeeping involved. And that means more code. In constrained embedded environments where every byte of program size is critical, this can be an automatic deal breaker.

Exceptions are easily abused as control flow mechanisms.

Have you ever seen code like this?

bool someCondition = false;
 
try
{
    if (checkSomeValue)
    {
        someCondition = true;
        throw 0;
    }
    if (checkSomeOtherValue)
    {
        someCondition = true;
        throw 0;
    }
    if (checkSomeOtherOtherValue)
    {
        someCondition = true;
        throw 0;
    }
 
    // ... More of the same
}
catch (...)
{
}
 
if (someCondition)
{
    // do something that relies on someCondition being true
}

This is just one example where an exception could be used to control the flow of code. It kind of works like a break. And it’s so very wrong. Why? When exceptions are thrown, the application suffers both a size cost and a performance cost. Performance-wise, this code is much slower than it should be.

How about this one?

try
{
    int a = std::stoi(someInput);
    printInt(a);
}
catch (const std::logic_error &)
{
    std::string b = someInput;
    printString(b);
}

Again, here we’re leveraging exceptions for the happy path. The code is slower than it should be. Remember, exceptions should be the exception. We’d actually get better performance in this example with error-codes.

Something that’s guaranteed not to throw today may not have such a guarantee tomorrow.

Once a function is declared nothrow and starts being used, its interface SHOULD be set in stone. Consumers of that function will expect it to never throw. It’s easy to amass a large body of code dependent on such a contract. So what happens when someone comes along and decides said function really needs to throw an exception? Probably a significant amount of effort expended visiting every place in the source code where that function is called. It’s that or or nothing at all, fingers-crossed, and hope for the best. What if that function is a virtual method in a base class? What if the function is part of an API with consumers beyond your reach? There be dragons.

To declare a function nothrow requires careful consideration and perhaps even some fortune-telling abilities. Most folks generally don’t bother with nothrow functions unless they’re intended for use with things like std::swap or std::move. Tread lightly.

Conclusion

Those are the big-ticket items, in my opinion. I’m sure some of you will have your own pro/cons that you feel should be added to the list. I encourage you to leave them in comments below.

So where do I lie on the love/hate spectrum? It depends. There’s a time and a place for everything. And exceptions are no exception (bah dum dum). Exceptions work great in some scenarios (e.g., a modern C++ codebase designed with exceptions in mind) and poor in others (e.g., a legacy C codebase, a library with bindings to other languages, etc.). As Kenny Rogers said, “You gotta know when to hold ’em , know when to fold ’em.” Experience will be your guide.

If you’d like to learn how to be better at writing exception-safe code, below are a few resources for you.

Jon Kalb’s presentations from CppCon 2014 are excellent. He does a deep dive into modern C++ exception handling. Highly recommended.

Jon Kalb’s “Exception Safe Code Part 1”
Jon Kalb’s “Exception Safe Code Part 2”
Jon Kalb’s “Exception Safe Code Part 3”

Scott Meyers covers a great number of exception-related best practices in his Effective C++ books (Effective C++, More Effective C++, and Effective Modern C++), all of which are required reading for any C++ developer.

Andrei Alexandrescu gave the presentation “Systematic Error Handling in C++” at the “C++ and Beyond” seminar back in 2012 thats very much still relevant today. In this talk, he explains a mechanism to bridge the error code/exception worlds with Expected and touches upon a newer version of ScopeGuard (something you should be intimately familiar with).

Good luck. And happy coding.

Learning to be a Good Person From a Phone Scammer

For one reason or another, I tend to get a lot of scam calls from fake Microsoft employees trying to convince me that my computer is infected with malware. The first thing they do is tell me that my PC has been taken over by hackers and malware and that the Microsoft servers keep getting reports from my machine. They walk me through running Window’s EventViewer and direct me to the Administrative Events log. This particular log is riddled with errors and warnings that occur during normal usage of Windows. You heard me right – normal usage. Regular, non-nerdy folks don’t know this. So the scammers use this to put folks on the defensive and it allows them to quickly build a trust relationship. It also allows them to easily convince their victims to install remote access software so they can “fix your machine” or “make it faster”. Their end game, of course, is to take over your PC and use it for God knows what. But I never allow it to get that far.

I usually take these guys on a wild goose chase. After 5 minutes or so, they get frustrated and hang up on me. I get a few laughs out of it. And 5 minutes on the phone with me means 5 minutes they’re not scamming some poor sap who doesn’t know any better.

But something strange happened on Friday night. I received one of these calls and took it a little further than I normally do. Let’s just say things got weird. You can listen to it below. Let me know what you think. 🙂