Bad Habit #1: Not using the right tool for the job
(or, using a shotgun to kill a fly)
By James R. Twine (Copyright 2002, James R. Twine)
[Previous Article In Segment] [Next
Article In Segment]
Remember your first "C" program? Most likely it was the ubiquitous
"Hello World!" program. Typically, this program is written like this:
int main( int iArgC, char *pArgV[] )
{
printf( "Hello World!\n" );
return( 0 );
}
Looks harmless enough, right? But it is my belief that having this as
your first program sets a bad precedent in your mind: it teaches you to use
something that "works", instead of something that "works well" (kudos to "Darth"
for that expression). What do I mean by that? As yourself the
following questions:
- What is the purpose of the printf(...)
function?
- What is it being used to do?
- Is there a better function available that was designed exactly for
the answer to #2?
If you have answered all three questions correctly, you should have come up
with a better function to use; and that function is the
puts(...) function. Why is puts(...)
the correct function to use in this example?
- The printf(...) function is designed to
provide formatted printing of output to the console. (Internally
it does a decent amount of setup to prepare its parser to look for "%"
symbols.)
- It is being used in the above example to output a static string and a newline. (No formatting is required, so why do we need to take the hit
of the setup of the internal parser?)
- The puts(...) function was designed to
output static strings and automatically append a newline.
At this point, some of you may be thinking something like: "the speed
difference is negligible on today's machines". And you may be
right... for this specific example that is being called once for a
13
character string... but what if it is being called more than once, and/or with a
longer string? What about being called 30 times, in a loop that iterates 5
times, in a function that gets called 10% of the time during normal execution of
your application? You have to look at the "big picture" here: these things
can add up rather quickly.
Actually, the problem is not necessarily this specific example of misuse; the
problem is getting into the habit of misuses like this. Contrary to
popular belief (or popular expression), practice
makes habit, not perfect. If you practice misuses like this,
they will become habit. So when it really matters, you may be in the habit
of going the "works" route, instead of the "works well" route, and THAT
is the real problem.
Following are some examples of this bad habit at work. These examples
come from production or publically available code written by developers
of varying experience levels.
Our first example just wants to do a simple string copy, but instead of using
the strcpy(...) function...
sprintf( cpDestBuffer, "%s", cpSourceString );
This one just wanted to output a string (in a buffer) to the console:
printf( "%s\n", cpSourceString );
//
// I Have Also Seen The Following...!
// (Note That This Is A Case Of EXTREME Stupidity,
// Not Often Found In The Wild!)
//
printf( "%s", "The Output Is:\"" );
printf( "%s", cpSourceString );
printf( "%s", "\"\n" );
This one demonstrates how to waste time trying to empty a string buffer (this
example also wastes the entire function call overhead to the strcpy(...)
function, and the scanning of an empty string; this was the
developer's way to "initialize" the string buffers upon entry to a function):
strcpy( caDestBuffer1, "" );
strcpy( caDestBuffer2, "" );
strcpy( caDestBuffer3, "" );
//
// Repeated For About 4 More Buffers...
//
The inappropriate use of a heavyweight solution to a simple problem is
touched on again in one of the Following Articles, where
we discuss the dangers of misusing string objects.
[Previous Article In Segment] [Next
Article In Segment]
|