|
|
|
Sponsored Link •
|
|
Advertisement
|
?:) play just for extra confusion, as
in the following macro/function:
int ProcessOddNums(int n);
int ProcessEvenNums(int n);
#ifdef __cplusplus
inline int ProcessNums(int n)
{
return (n % 2) ? ProcessOddNums(n) :
ProcessEvenNums(n);
}
#else /* ?__cplusplus */
# define ProcessNums(n) ((n % 2) ? ProcessOddNums(n)
: ProcessEvenNums(n))
#endif /* __cplusplus */
By defining the C++ form as an inline, we not only avoid
stepping on any other ProcessNums
symbol, we can also step into the
ProcessNums() function, and avoid the
often irritating/confusing mental disconnect one
experiences when thinking one is about to step into one
function, and ends up in another, leading to time-wasting
existentialist digressions — how did I get here? It also
significantly eases the business of fine-grained
placement of breakpoints, and gives us a stack frame in
which to play around and look at function parameters
before diving down into the worker functions. This fact
alone has proven its worth many times over in our use of
the technique.
TheFunc in C and C++. As you can
imagine, such bugs are extremely hard to find.
The alternative is to make a single point of definition, based on "safe(r) macros", and then define the user- facing macros/functions in terms of those macros, hence:
# ifdef ACMELIB_MULTI_THREADING
# define ACMELIB_TheFunc TheFuncMT
# else /* ? ACMELIB_MULTI_THREADING */
# define ACMELIB_TheFunc TheFuncST
# endif /* ACMELIB_MULTI_THREADING */
/* The actual mappings for C / C++ */
#ifdef __cplusplus
inline void TheFunc() { ACMELIB_TheFunc(); }
#else /* ? __cplusplus */
# define TheFunc ACMELIB_TheFuncMT
#endif /* __cplusplus */
There's a modest increase in code size and effort, but it's a manifest gain in robustness, and a final cherry on the maintainability cake.
The cost is a slight increase in admittedly arcane-
looking code, but such things are readily amenable to
being auto-generated by script. You can also choose to
define them in a separate file that is
#include'd into your main,
handwritten, header file, so you keep your main header
nice and neat and comprehensible to users of your code.
Using this technique, you can avoid a host of troubles for yourself and, more importantly, for the users of your code. Now, if only we can get the large software companies to play ball�
Thank you for reading,
Bjorn Karlsson and Matthew Wilson
http://www.bigboyandrunningbear.com/
recls is one of the exemplar libraries for Matthew's
Positive Integration column for C/C++ User's Journal. The column
is concerned with integrating different languages with C
and C++, and uses different libraries to highlight the
issues involved.
Matthew Wilson is a software development consultant for Synesis Software, and creator of the STLSoft libraries. He is author of the Imperfect C++ (Addison-Wesley, 2004), and is currently working on his next two books, one of which is not about C++. Matthew can be contacted via http://imperfectcplusplus.com/.
Bjorn Karlsson is proud to be a C++ designer, programmer, teacher, preacher, and student. He has finally learned enough about C++ to realize how little he knows. When not reading or writing articles, books, or code, he has the privilege to be a part of the Boost community, and a member of The C++ Source Advisory Board. His book, Beyond The C++ Standard Library: An Introduction to Boost, will be published by Addison-Wesley in 2005. He appreciates it when people send him interesting emails at bjorn.karlsson@readsoft.com.
|
Sponsored Links
|