Re: Conscious antipattern behavior
From: E. Robert Tisdale (E.Robert.Tisdale_at_jpl.nasa.gov)
Date: 01/12/04
- Next message: Jonathan Turkanis: "Re: Conscious antipattern behavior"
- Previous message: Shiva: "===Welcome to comp.lang.c++! Read this first."
- In reply to: Ray Gardener: "Conscious antipattern behavior"
- Next in thread: Jonathan Turkanis: "Re: Conscious antipattern behavior"
- Reply: Jonathan Turkanis: "Re: Conscious antipattern behavior"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 11 Jan 2004 21:04:22 -0800
Ray Gardener wrote:
> I've always wondered what other C++ programmers
> fail to do while coding even though they know
> what they're doing is... naughty (and some of the
> items below occur in other languages, of course).
>
> People make these slip-ups all the time accidentally,
> but what I'm getting at is when we make them while
> we consciously _know_ that we're being bad. This is
> the more interesting phenomenon because I tend to
> interpret consciously "fighting the language" or
> consciously "not using the language as intended"
> as an indication that the language or the
> development environment could be improved.
>
> (Granted, in C++ the "right way" is vague because
> C/C++ has broad expressive capability, but there
> are informal standards of good coding practice
> that we all more or less know).
>
> Examples:
>
> - Duplicating code via copy/paste
> instead of [defining and calling functions].
You mean "manual inlining" to save the cost of a function call
and permit the C++ compiler to optimize the code.
The alternative is to declare functions *inline*
so that the compiler will automatically inline them.
> - Failing to make methods and other things 'const'
> when they should be.
When should they be const?
> - Failing to assert what should be asserted.
An example would help.
The C preprocessor assert macro is only useful
for detecting and debugging programming errors.
> - Not using templates when they would be suitable.
When are templates suitable?
> - Trying patches instead of refactoring
> (only to sooner or later refactor anyway
> and then feeling sheepish about it).
Refactoring takes time and costs money.
Feeling sheepish is free.
> - Passing references to objects to functions
> that give too much info to the function
> when it only needs a few members of the object.
>
> - Making "incestuous" calls instead of using
> signal/slots/broadcasters/listeners or similar
> design patterns.
>
> - Using your own container classes instead of STL,
> when STL would have been the better choice.
Never reference STL container classes
(or any built-in type) directly in your application source code.
Wrap the STL container class is your own class definition
so that you can substitute something else later if necessary.
> - Using #define macros instead of template functions.
>
> - Using boolean types instead of enums even though
> you know that the type will soon grow beyond
> two possible states.
>
> - Letting a class grow until it has a zillion members.
Group the members into classes as appropriate.
> - Using pointers instead of references
> when references would have been better.
When are references better?
> - Putting "is-a" members inside a class instead of
> making a new subclass, and having callers query
> those members in a roll-your-own form of RTTI.
>
> - Using error code returns or object error states
> instead of exceptions.
You can return an exception object instead of an error code
but you can use the function in an expression.
> - Letting class members be public that shouldn't be.
When should class members be public?
> - Letting a function grow really long only because
> technically it doesn't actually have to be broken
> down into subroutines because none of them would
> be called from anywhere else anyway.
Functional decomposition helps make your code
easier to read, understand and maintain.
> - Using more and more preassigned function args
> to avoid having to declare another function of
> a similar name, or the reverse -- not using
> preassigned args where they make sense.
Where do they make sense?
> - [Implementing functions] with names like "add" and "mul"
> instead of using operator overloading.
>
> - Being inconsistent in naming, spelling,
> interface strategies, etc.
>
> - Declaring more global objects than necessary.
When is it *necessary* to declare global objects?
> - Placing code that makes sense in a shareable library
> into application-side classes (or just letting it
> sit and evolve on the app side while telling yourself
> that you'll factor it out "someday").
>
> - Using char* instead of a more Unicode-friendly string type.
>
> - Using two member vars to track a state of only
> one logical member (e.g., a bool and a pointer when
> the pointer's being null will suffice to indicate
> a false state).
>
> - Specifying constants by value instead of by macro or enum.
>
> - Using int instead of size_t when size_t is the
> better type (e.g., you're declaring a zero-based counter).
>
> - Using #define's instead of enums.
>
> - Using external enums instead of class member enums.
>
> - Using a struct instead of a class (even when it becomes
> painfully obvious that it should be a class).
There is *no* difference between a struct and a class in C++
except that class members are private by default and
struct members are public by default.
> - Solving a typical problem one way, then the same
> problem a different way somewhere else because
> it is superior, but failing to go back and upgrade
> the usages of the first implementation.
>
> - Using malloc/free in some places and operator new/delete
> in others, for no particular reason.
>
> Obviously some of the above are rational tactical
> decisions under certain situations, so I'm not
> including those combinations of choice and context.
>
> I'm interested in finding out what poor choices
> C++ programmers consciously make and why. Was it
> easier at the time? More expedient? Force of habit?
> Does the dev environment foster those habits
> (e.g., an editor with great copy/paste might
> actually be bad)? Is good coding a matter of
> willpower or do certain tools turn the tide?
> Does extreme or paired-up programming help
> combat these tendencies? Is perfect discipline
> even desirable?
The C++ computer programming language introduced
many subtle new features to C programmers.
They are still learning to use them. It takes time
and many of the older, more experienced programmers
will never fully appreciate them and take advantage of them.
Most C++ programmers are amateur programmers.
They write C++ programs to help them do the work
that they were hired and paid to do.
They typically learn just one language
and they try to use it for everything.
They learn just enough about the language
to do what they need to do.
They avoid the more complicated and subtle features
of the language and use the subset of features
with which they have experience and that
they believe they really understand.
Computer programming is *evolutionary* -- not revolutionary.
You must wait until this older generation of programmers
retires (or passes away) before you can expect real improvement.
- Next message: Jonathan Turkanis: "Re: Conscious antipattern behavior"
- Previous message: Shiva: "===Welcome to comp.lang.c++! Read this first."
- In reply to: Ray Gardener: "Conscious antipattern behavior"
- Next in thread: Jonathan Turkanis: "Re: Conscious antipattern behavior"
- Reply: Jonathan Turkanis: "Re: Conscious antipattern behavior"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|