|
April 2006
April 21, 2006
Band-Aid Safety
The first rule of shop safety is "keep the soft parts away from the whirly parts." If you get your finger tangled up with a saw blade, it's not much comfort to know that you've got a box of band-aids in the medicine cabinet. You have to pay attention, so that accidents don't happen. Unfortunately, the buzz in the programming community about "safety" focuses on treating the results of accidents instead of avoiding them.
If you call strcpy with a buffer that's too short, you're in trouble. That's the kind of thing that malicious applications take advantage of in operating systems and browsers. The solution isn't to rewrite strcpy to take an additional argument that gives the size of the buffer, so that it can refuse to copy too many characters. It's to rewrite the code that calls it to ensure that the buffer is large enough.
There's a discussion on one of the C++ newsgroups about requiring default initialization of class members that aren't listed in the constructor initialization list, to make initialization "safer." There's also a suggested added syntax for saying that you don't want a member initialized. Apparently the thinking is that initializing something to the wrong value is better than not initializing it. Either way, though, it's a mistake, and mistakes need to be fixed.
In both cases, the right way to approach the problem is to design the application so that these errors don't occur. Check the length of an input string when it comes in, and if it's too long, reject it. Review constructors to make sure that they properly initialize members that require initialization. That's your responsibility as a professional programmer. Write correct code, and you won't have to worry about adding safety hacks.
Posted by Pete Becker at 10:21 AM Permalink
|
April 19, 2006
More News From the Front
The next revision of the C++ Standard, tentatively titled C++0x (the 'x' is a placeholder, intended to suggest that the revision will be finished before 2010, although some people like to remind us that "0x" introduces a hexadecimal constant, so C++0x really has to be finished by 2015), will have language and library changes that fix problems in the current revision.
One of the most annoying things about writing template code is that when you have nested templates you have to separate the two >'s that terminate them. You have to write X > instead of the more natural X>, because >> is a token. One of the language changes is to allow X>. The compiler will recognize that it's reading a template instantiation, and treat the two > characters as separate tokens.
Another addition is "extern template", which provides a syntax for telling the compiler that a specific template instantiation will be provided somewhere else. If you write shared libraries you've had to deal with this problem: you put a template instantiation into a shared library, and you don't want the compiler to use that version of the code instead of expanding the template where it's used. "extern template" is a common extension, and the language definition now (well, when the new version is approved, a few years from now) blesses it.
I'm running out of time; more later.
Posted by Pete Becker at 08:33 AM Permalink
|
April 18, 2006
Multithreading: Just Say No
Remember that old anti-drug ad that started with an image of an egg and the narrator saying "Here's your brain," followed by an image of the egg being broken into a hot skillet, and the narrator saying "Here's your brain on drugs"? Replace "brain" with "program" and "drugs" with "multi-threading." Writing fast, robust multi-threaded programs is hard. Most programmers (including me) can't do it.
Writing fast, robust multi-threaded programs is not a programming problem. It's a design problem and a process problem. Each application must be designed with multi-threading in mind, and the programmers who write the application must follow the design. Programming languages and libraries can provide low-level tools (mutexes, once functions, etc.) that provide synchronization services, but if these tools aren't controlled by a sound design enforced through a rigorous review process, the resulting application will quickly turn into scrambled eggs.
Posted by Pete Becker at 07:29 AM Permalink
|
April 17, 2006
News From the Front
The C++ Standards Committee met two weeks ago in Berlin. There's a lot going on, but from my perspective as a library implementor (and, admittedly, the author of an upcoming book), the biggest event was the acceptance of most of TR1 into the next C++ Standard.
TR1 is the Technical Report on C++ Library Extensions. It's been approved by the standards committee, and has made its way through the ISO bureaucracy to the point where it's official. But being official isn't the same as being part of the standard: It's advice of possible future directions. But now most of it is part of the next standard, so C++ compilers that claim to conform to the next ISO standard will have to provide, in addition to the current standard library, the newly added parts of TR1: shared_ptr and its kin, reference_wrapper, function, mem_fn, bind, type traits, random number generators, fixed size array and hashed containers, regular expressions, and most of the C99 library additions. If you want the details, the most recent draft of the TR is available at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf. Or (caution: shameless plug) buy my book when it comes out this summer. "The C++ Standard Library Extensions: a Tutorial and Reference", published by Addison-Wesley.
Posted by Pete Becker at 07:59 AM Permalink
|
April 14, 2006
Too Many Templates
When you're lost in template land, instead of asking "how can I make this $*#*&& template work," ask yourself whether the problem you're seeing might have nothing to do with templates.
All too often you see questions on newsgroups about template code that doesn't compile. Many times the problem has nothing to do with templates; they're just a distraction. So try the same thing without templates and see if you can get it to work. Then take the lesson you learned over into your template code.
For example someone recently tried to derive from two different instantiations of the same template:
template struct S
{
void f(S);
};
struct Derived : S, S
{
void g()
{
f(1);
}
};
The code went on to create an object of type Derived and call its member function g. Didn't work: the compiler said the call to f(1) was ambiguous.
Try it with two ordinary classes instead of a template:
struct S_int
{
void f(int);
};
struct S_double
{
void f(double);
};
struct Derived : S_int, S_double
{
void g()
{
f(1);
}
};
Same error, same problem: the two versions of f don't overload, because they're not defined in the same scope.
Templates have a well-deserved reputation for creating nasty error messages. But sometimes it's not the template's fault.
Posted by Pete Becker at 01:04 PM Permalink
|
|