Re: Alternatives to #define?

From: Carl Ribbegaardh (carl_ribbegaardh_Remove_theese_extra_words__at_hotmail.com)
Date: 07/04/04


Date: Sun, 4 Jul 2004 00:17:23 +0200


"Mark A. Gibbs" <x_gibbsmark@rogesr.com_x> wrote in message
news:aqzFc.3242$FJt1.1318@news04.bloor.is.net.cable.rogers.com...
>
> just use this.
>
> >>>namespace MyUtils
> >>>{
> >>> inline void doStuff()
> >>> {
> >>> doThis();
> >>> doThat();
> >>> }
> >>>}
> >>
> >>That works, and most C++ purists would recommend it,
> >>but I think it sucks. Too complicated. KISS.
> >>Use the macro instead.
>
> this is probably the most bizarre thing i've read in a while. it works,
> huh?:
>
> for (int i = 0; i < 10; ++i)
> STUFF
>
> vs.
>
> for (int i = 0; i < 10; ++i)
> doStuff();
>
> "kiss" that.
>
> > But macros can be difficult to follow too. This example is very
simplistic,
> > but for example logging macros and testing macros can be difficult to
read
> > and maintain. But I do like how the compiler has an opportunity to
remove
> > large parts of the code by switching a compiler flag.
>
> inline functions were largely created for the explicit purpose of
> eliminating macros.
>
> #define DO_STUFF doThis(); doThat();
>
> and
>
> inline void doStuff()
> {
> doThis();
> doThat();
> }
>
> should produce *exactly* the same output instructions under most
> circumstances (of course, the compiler is free to ignore the inline
> suggestion, and most do under certain circumstances). that's what they
> were created for.
>
> you want the power to be able to effectively turn that function off in
> certain compile-time conditions (eg, removing it in a release build)? no
> problem:
>
> inline void doStuff()
> {
> #ifdef DEBUG
> doThis();
> doThat();
> #endif
> }
>
> that will be a no-op on any compiler worth its salt if DEBUG is not
> defined. need a parameter? piece of cake:
>
> inline void doStuff(int param)
> {
> doThis(param);
> doThat(param);
> }
>
> just try that with macros:
>
> #define STUFF(x) doThis(x); doThat(x);
> STUFF(++i); // uh oh!
>
> also, what if you need a dummy/default variable for the call?
>
> inline void doStuff()
> {
> int temp;
> doThis(&temp);
> doThat(temp);
> }
>
> works with the macro? well...
>
> #define STUFF int temp; doThis(&temp); doThat(temp);
>
> void foo()
> {
> STUFF
> // some code
> STUFF // bang!
> }
>
> incidently:
>
> class MyUtils
> {
> public:
> static void doStuff() // implicit inline
> {
> doThis();
> doThat();
> }
> };
>
> would work, and may be valid in certain instances. i was involved in a
> lengthy debate about the merit of such a design pattern a while back. no
> real conclusion was reached, but i believe that 99% of the time this
> method is unnecessary and convoluted, and it's even occasionally
> dangerous. however, you're the programmer, do what you will.
>
> > I'm just interested in learning different techniques of performing the
same
> > task, just to improve my toolbox :)
>
> bien sur. macros do have their place. and all the problems i presented
> above with the macros *could* be fixed. but seriously, how can you think
> inline funcitons are "too complicated" when you have to take so much
> care with them? use them only when direct text substitution is desired.
> _never_ use the preprocessor in place of c++ language constructs.
>
> as far as i can think right now, inline functions (and inlined static
> public class members of course) are about the only way to do what you
> want. macros *can* do it, if you're careful, but are most definitely not
> the best way to do it.
>
> of course, regular non-inlined functions could do the same thing,
> although possibly with additional overhead. i say this because often in
> the rush to optimize, rationality goes out the window. after all, you're
> already paying for the overhead *twice* with doThis() and doThat(). if
> either function takes any practical length of time, the overhead in
> calling doStuff() is pretty much marginalized.
>
> also, an optimizing compiler would probably realize that setting up the
> stack frame in doStuff is unnecessary, so the entire cost of the
> function (not counting doThis() and doThat(), of course) comes down to
> two jump instructions. that's two jump instructions, likely a call and a
> ret on x86's, and possibly even less in special cases. is that too
> expensive?
>
> and that's assuming the compiler doesn't inline it anyway. stay away
> from macro crap. trust your compiler... but use your profiler.
>
> mark
>

Very enlightening post. I think that you might have mixed up who thought
what about macros and inline functions, but it really doesn't matter.
This was exactly the info about alternatives to macros I was looking for. :)
Thanks a lot!

/Carl



Relevant Pages

  • Re: Alternatives to #define?
    ... > but for example logging macros and testing macros can be difficult to read ... But I do like how the compiler has an opportunity to remove ... inline void doStuff() ...
    (comp.lang.cpp)
  • Re: inline functions
    ... A function declared with the function specifier "inline". ... > When should we declare a particular function as inline? ... i.e. the compiler is free to do nothing. ... Then why not use macros? ...
    (comp.lang.c)
  • Re: inline and macro
    ... Hi, inline fuctions and macros shoud be equally fast (actually, ... I prefer inline functions to macros, ... The compiler may or may not inline a function declared inline. ...
    (microsoft.public.vc.language)
  • [PATCH] [9/11] x86: Replace NSC/Cyrix specific chipset access macros by inlined functions.
    ... With the macros a line like this fails: ... * NSC/Cyrix CPU indexed register access macros ... static inline void sync_core ... +static inline void setCx86 ...
    (Linux-Kernel)
  • Re: [PATCH 1/1] i386: Geodes TSC is not neccessary to mark tu unstable
    ... Replace NSC/Cyrix specific chipset access macros by inlined functions. ... * NSC/Cyrix CPU indexed register access macros ... static inline void sync_core ... +static inline void setCx86 ...
    (Linux-Kernel)