Names like tmp, retval, and foo are usually cop-outs that mean “I can’t think of a name.” Instead of using an empty name like this, pick a name that describes the entity’s value or purpose.
For example, here’s a JavaScript function that uses retval:
var euclidean_norm = function (v) {
var retval = 0.0;
for (var i = 0; i < v.length; i += 1)
retval += v[i] * v[i];
return Math.sqrt(retval);
};
It’s tempting to use retval when you can’t think of a better name for your return value. But retval doesn’t contain much information other than “I am a return value” (which is usually obvious anyway).
A better name would describe the purpose of the variable or the value it contains. In this case, the variable is accumulating the sum of the squares of v. So a better name is sum_squares. This would announce the purpose of the variable upfront and might help catch a bug.
For instance, imagine if the inside of the loop were accidentally:
retval += v[i];
This bug would be more obvious if the name were sum_squares:
sum_squares += v[i]; // Where's the "square" that we're summing? Bug!
Here’s an example from the codebase at Google. In C++, if you don’t define a copy constructor or assignment operator for your class, a default is provided. Although handy, these methods can easily lead to memory leaks and other mishaps because they’re executed “behind the scenes” in places you might not have realized.
As a result, Google has a convention to disallow these “evil” constructors, using a macro:
class ClassName {
private:
DISALLOW_EVIL_CONSTRUCTORS(ClassName);
public:
...
};
This macro was defined as:
#define DISALLOW_EVIL_CONSTRUCTORS(ClassName) \
ClassName(const ClassName&); \
void operator=(const ClassName&);
By placing this macro in the private: section of a class, these two methods become private, so that they can’t be used, even accidentally.
The name DISALLOW_EVIL_CONSTRUCTORS isn’t very good, though. The use of the word “evil” conveys an overly strong stance on a debatable issue. More important, it isn’t clear what that macro is disallowing. It disallows the operator=() method, and that isn’t even a “constructor”!
The name was used for years but was eventually replaced with something less provocative and more concrete:
One of our programs had an optional command-line flag named --run_locally. This flag would cause the program to print extra debugging information but run more slowly. The flag was typically used when testing on a local machine, like a laptop. But when the program was running on a remote server, performance was important, so the flag wasn’t used.
You can see how the name --run_locally came about, but it has some problems:
A new member of the team didn’t know what it did. He would use it when running locally (imagine that), but he didn’t know why it was needed.
Occasionally, we needed to print debugging information while the program ran remotely. Passing --run_locally to a program that is running remotely looks funny, and it’s just confusing.
Sometimes we would run a performance test locally and didn’t want the logging slowing it down, so we wouldn’t use --run_locally.
The problem is that --run_locally was named after the circumstance where it was typically used. Instead, a flag name like --extra_logging would be more direct and explicit.
But what if --run_locally needs to do more than just extra logging? For instance, suppose that it needs to set up and use a special local database. Now the name --run_locally seems more tempting because it can control both of these at once.
But using it for that purpose would be picking a name because it’s vague and indirect, which is probably not a good idea. The better solution is to create a second flag named --use_local_database. Even though you have to use two flags now, these flags are much more explicit; they don’t try to smash two orthogonal ideas into one, and they give you the option of using just one and not the other.