Compared to what?
A couple of months ago, I examined some common alternatives for representing and manipulating memory-mapped devices in C.1 I followed that with a column on why classes in C++ offer a better alternative than anything you can do in C.2 By "better," I mean that well-written classes yield interfaces that are typically easier to use correctly and harder to use incorrectly.3
On the other hand, designing and implementing a well-written C++ class often requires attention to details that don't apply when you program in C. For example, one of the easiest ways to misuse a structure object in C is to fail to initialize it properly. In C++, a class can have special member functions, called constructors, that provide guaranteed initialization for objects of that class type. The guarantee isn't absolute--you can subvert it using a cast--but it's nonetheless effective at reducing the incidence of uninitialized objects.
At the end of my last column, I note that "using classes raises other issues--such as whether to use constructors--that just don't arise when using C structures. I'll have more to say about these issues in the future." Despite this cautionary note, some readers posted comments criticizing my coding example for not addressing initialization. They objected not only to the absence of constructors, but also to my use of casting to initialize pointers and references referring to memory-mapped class objects.
Other readers defended the code, arguing that construction and destruction are inappropriate operations for memory-mapped devices. I appreciate the backup, but I actually agree that omitting constructors and using casts can be problematic. That's why I intend to say something about them, but not just yet. Rather, I'm going to respond to a different concern first, not because it's any more important, but because the discussion provides background that will be helpful when discussing initialization issues.
Concerns about performance
Beyond their concerns about initialization and type safety, a few readers expressed concern that using a pointer to access a class object representing a memory-mapped device incurs a performance penalty by somehow adding unnecessary pointer indirection. Some considered the performance hit to be a serious problem, while others suggested it wasn't nearly so bad in practice.
Interestingly, no one complained that using C structures to represent memory-mapped devices incurs a similar performance penalty. So I wonder: Is the allegation that using a C++ class is more expensive than using a C structure? Or is it that using pointers to access memory-mapped class objects is more costly than using some other means?
If accessing memory-mapped class objects through pointers incurs a performance penalty, we should first ask "Compared to what?" In other words, if using pointers is slow, then what else is there that might be faster?
This month, I'll enumerate the available alternatives for placing objects into memory-mapped locations. Next month, I'll consider alternative implementations that eliminate the need to use pointers to access memory-mapped devices.