C/C++ Users Journal November, 2004
There's widespread agreement that you can get into trouble with pointer arithmetic. Quite a few programming languages other than C and C++ solve the potential problems by simply not having pointers. In place of pointer arithmetic, they make do with array subscriptingnot quite the same thing, but often close enough. In place of data allocation and freeing, they provide garbage collection, which can be sometimes better, sometimes worse. And in place of function pointers, they use delegates or some other similarly structured equivalent. The idea is to make you the programmer meet the compiler well more than halfway, so it can generate the necessary checks and keep you from generating the nastier bugs.
As computers get larger and faster, I find myself ever more tolerant of such constraints. I can think of few things worse than chasing a storage overwrite bug, unless it's a wild jump into nowhere in particular, or a dangling pointer to freed storage, or a steady memory leak that eventually brings down a server. With more and more spare capacity at our disposal, it's only sensible to spend some of it on insurance against all nighters. Or worse, flaky systems and security gaffes that make it into the field.
But I just can't bring myself to abandon pointers altogether. For one thing, I still find plenty of occasions where code speed and size still matter. For another, I find that banning pointers is neither necessary nor sufficient for producing reliable software. It isn't necessary if you write cleanly and enforce a proper discipline. It isn't sufficient because there are too many other ways to sabotage the best efforts of a compiler and runtime to protect you from yourself.
Yes, there's always the "sandbox" approach. Your web browser can download Java code from untrusted sources and run it on your machine because the runtime interpreter won't let it do much. It can't read or write your files, or seize control of your OS. About all that's left is various ways to make your display twitch. (I got tired of the headaches caused by all those dancing letters years ago, and began disabling Java content. Apparently millions of fellow surfers came to the same conclusion, because I seldom hit a web site where it matters anymore.)
Discipline is always necessary, and constraining code is never sufficient, at least not if you want to get something done. Thus, I find myself looking for safer ways to use pointers to advantage, rather than simply pretend I don't need them.
And that's why I was particularly happy to see a proposal come out of Microsoft a year or so ago. Martyn Lovell and a few of his fellow travelers had just weathered a major security review of Microsoft code. (I don't have to remind you why. Attacking the hundreds of millions of Windows systems connected to the Internet has become a popular indoor sport among hackers around the world.) It was not hard to identify the Standard C Library functions most often implicated in storage overwrites, perhaps the commonest form of security gaffe. And it was not much harder to contrive a set of safer substitutes. So they did.
The result is a Technical Report on Secure C, which is now working its way through WG14, the C Standards Committee. It is not a wholesale rewrite of the Standard C Library. Nor is it an attempt to outlaw the use of pointers in C. Neither approach would get much traction in the broader C community. Rather, it provides better assistance to programmers who endeavor to write cleaner safer code, and to agents that endeavor to spot potential lapses. Those agents can be either smarter compilers or human code reviewers. In either case, the basic idea is to sacrifice just a small amount of performance for a real improvement in reliability.
The goal is to increase visibility. If you call a function with a buffer, you have to say how big it is. The function will check, and it'll fail safe if the buffer isn't big enough. More important, however, the added length parameter forces the programmer to think about how big the buffer has to be and actually is. And it gives future reviewers critical information right at the point of the call, where it's most needed. Practically all of the Secure C additions are variations on this theme.
That approach meshes well with my notions of good coding discipline married with a minimum of overhead. It took me just a couple of days to produce a Secure C Library, which is now tracking the evolving TR. I figure anything that small that can help us write safer code has to be a Good Thing.
P.J. Plauger
Senior Contributing Editor
pjp@plauger.com