Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Alternatives to #define?

Reply
Thread Tools

Alternatives to #define?

 
 
Carl Ribbegaardh
Guest
Posts: n/a
 
      07-02-2004
What other c++ constructs can I use instead of #define for executing a
couple of functions?
Example:

#define DO_STUFF doThis(); doThat();

I'd guess that I can either use a template function, an inlined function or
an inlined static method.

//1
namespace MyUtils
{
template<>
void doStuff()
{
doThis();
doThat();
}
}

//2
namespace MyUtils
{
inline void doStuff()
{
doThis();
doThat();
}
}

//3
class MyUtils
{
public:
static inline void doStuff() const
{
doThis();
doThat();
}
}

I *believe* that the template version always is inlined, and that the other
2 versions is probably inlined.
Are theese approaches correct?
Which should be preferred?
Are there any other better way?

/Carl


 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      07-02-2004

"Carl Ribbegaardh" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> What other c++ constructs can I use instead of #define for executing a
> couple of functions?
> Example:
>
> #define DO_STUFF doThis(); doThat();
>
> I'd guess that I can either use a template function, an inlined function

or
> an inlined static method.
>
> //1
> namespace MyUtils
> {
> template<>
> void doStuff()
> {
> doThis();
> doThat();
> }
> }
>
> //2
> namespace MyUtils
> {
> inline void doStuff()
> {
> doThis();
> doThat();
> }
> }
>
> //3
> class MyUtils
> {
> public:
> static inline void doStuff() const
> {
> doThis();
> doThat();
> }
> }
>
> I *believe* that the template version always is inlined, and that the

other
> 2 versions is probably inlined.


No that is not true. I guess you are thinking of the exception that
templates have from the normal one definition rules for functions and
classes. But that's an entirely seperate issue.

> Are theese approaches correct?


They are all correct.

> Which should be preferred?


The second

> Are there any other better way?


What's wrong with the second method? Why is it even an issue?

john


 
Reply With Quote
 
 
 
 
Carl Ribbegaardh
Guest
Posts: n/a
 
      07-02-2004

"John Harrison" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> "Carl Ribbegaardh" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > What other c++ constructs can I use instead of #define for executing a
> > couple of functions?
> > Example:
> >
> > #define DO_STUFF doThis(); doThat();
> >
> > I'd guess that I can either use a template function, an inlined function

> or
> > an inlined static method.
> >
> > //1
> > namespace MyUtils
> > {
> > template<>
> > void doStuff()
> > {
> > doThis();
> > doThat();
> > }
> > }
> >
> > //2
> > namespace MyUtils
> > {
> > inline void doStuff()
> > {
> > doThis();
> > doThat();
> > }
> > }
> >
> > //3
> > class MyUtils
> > {
> > public:
> > static inline void doStuff() const
> > {
> > doThis();
> > doThat();
> > }
> > }
> >
> > I *believe* that the template version always is inlined, and that the

> other
> > 2 versions is probably inlined.

>
> No that is not true. I guess you are thinking of the exception that
> templates have from the normal one definition rules for functions and
> classes. But that's an entirely seperate issue.
>
> > Are theese approaches correct?

>
> They are all correct.
>
> > Which should be preferred?

>
> The second
>
> > Are there any other better way?

>
> What's wrong with the second method? Why is it even an issue?
>


The issue is that I dont *know*.
I'm currently just guessing/believing.

So the 1st version isn't inlined? Why I thought it would be, is that I've
read lines like "templates are inlined by definition" but I might have
interpreted/read/remembered it wrong. Any elaboration on why or why not
would be much appreciated.

Thanks!


 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      07-02-2004

"Carl Ribbegaardh" <carl_ribbegaardh_Remove_theese_extra_words_@hotma il.com>
wrote in message news:(E-Mail Removed)...
>
> "John Harrison" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> >
> > "Carl Ribbegaardh" <(E-Mail Removed)> wrote in

message
> > news:(E-Mail Removed)...
> > > What other c++ constructs can I use instead of #define for executing a
> > > couple of functions?
> > > Example:
> > >
> > > #define DO_STUFF doThis(); doThat();
> > >
> > > I'd guess that I can either use a template function, an inlined

function
> > or
> > > an inlined static method.
> > >
> > > //1
> > > namespace MyUtils
> > > {
> > > template<>
> > > void doStuff()
> > > {
> > > doThis();
> > > doThat();
> > > }
> > > }
> > >
> > > //2
> > > namespace MyUtils
> > > {
> > > inline void doStuff()
> > > {
> > > doThis();
> > > doThat();
> > > }
> > > }
> > >
> > > //3
> > > class MyUtils
> > > {
> > > public:
> > > static inline void doStuff() const
> > > {
> > > doThis();
> > > doThat();
> > > }
> > > }
> > >
> > > I *believe* that the template version always is inlined, and that the

> > other
> > > 2 versions is probably inlined.

> >
> > No that is not true. I guess you are thinking of the exception that
> > templates have from the normal one definition rules for functions and
> > classes. But that's an entirely seperate issue.
> >
> > > Are theese approaches correct?

> >
> > They are all correct.
> >
> > > Which should be preferred?

> >
> > The second
> >
> > > Are there any other better way?

> >
> > What's wrong with the second method? Why is it even an issue?
> >

>
> The issue is that I dont *know*.
> I'm currently just guessing/believing.
>


Well method two is using one function to call two others. It's perfectly
common programming to solve a common problem. The other methods introduce
extra language features to create a more complex solution to a simple
problem.

> So the 1st version isn't inlined? Why I thought it would be, is that I've
> read lines like "templates are inlined by definition" but I might have
> interpreted/read/remembered it wrong. Any elaboration on why or why not
> would be much appreciated.
>


If you read that it was wrong. As I said I think you might have read that
template functions usually go in header files which makes them a little like
inline functions (which also usually go in header files), but this is for
technical issues to do with how templates are compiled. It has nothing to do
with whether the template function call itself is inlined.

john


 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      07-02-2004
Carl Ribbegaardh wrote:

> What other c++ constructs can I use instead of #define for executing a
> couple of functions?
> Example:
>
> #define DO_STUFF doThis(); doThat();
>
> I'd guess that I can either use a template function, an inlined
> function or an inlined static method.
>
> //1
> namespace MyUtils
> {
> template<>
> void doStuff()
> {
> doThis();
> doThat();
> }
> }


What's that template good for? Actually, I don't think this is valid,
since it doesn't have any template parameters.

> //2
> namespace MyUtils
> {
> inline void doStuff()
> {
> doThis();
> doThat();
> }
> }
>
> //3
> class MyUtils
> {
> public:
> static inline void doStuff() const
> {
> doThis();
> doThat();
> }
> }


That's incorrect. You cannot make a static member function const, as
that wouldn't make sense. Making a member function const means that it
can be called on const objects, but a static member function isn't
called on any object at all.

> I *believe* that the template version always is inlined, and that the
> other 2 versions is probably inlined.


No. The template might be inlined or it might not, just like any other
function.

 
Reply With Quote
 
Robbie Hatley
Guest
Posts: n/a
 
      07-03-2004
"Carl Ribbegaardh" <(E-Mail Removed)> wrote:

> #define DO_STUFF doThis(); doThat();


I actually like that. Simple, direct, ALWAYS inlined.

> namespace MyUtils
> {
> template<>
> void doStuff()
> {
> doThis();
> doThat();
> }
> }


I tried compiling that, got "Error: non-template
used as template."

> 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.

> class MyUtils
> {
> public:
> static inline void doStuff() const
> {
> doThis();
> doThat();
> }
> }


"error: static member function `static void MyUtils::doStuff()'
cannot have `const' method qualifier"

Why stir up trouble with complicated stuff when trying to
solve a simple problem? Usually the simpliest workable
solution is the best. Sometimes a macro is the thing that fits
that bill.


--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant










----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
 
Reply With Quote
 
Carl Ribbegaardh
Guest
Posts: n/a
 
      07-03-2004
"Robbie Hatley" <lonewolfintj at pacbell dot net> wrote in message
news:40e655f9_2@127.0.0.1...
> "Carl Ribbegaardh" <(E-Mail Removed)> wrote:
>
> > #define DO_STUFF doThis(); doThat();

>
> I actually like that. Simple, direct, ALWAYS inlined.
>
> > namespace MyUtils
> > {
> > template<>
> > void doStuff()
> > {
> > doThis();
> > doThat();
> > }
> > }

>
> I tried compiling that, got "Error: non-template
> used as template."


Yes, I just wrote it in the news reader. Think of it as pseudo code

>
> > 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.
>
> > class MyUtils
> > {
> > public:
> > static inline void doStuff() const
> > {
> > doThis();
> > doThat();
> > }
> > }

>
> "error: static member function `static void MyUtils::doStuff()'
> cannot have `const' method qualifier"
>


Yes, the const should probably go away. It's also just invented on the fly
to show roughly how I thought. Pseudo code

> Why stir up trouble with complicated stuff when trying to
> solve a simple problem? Usually the simpliest workable
> solution is the best. Sometimes a macro is the thing that fits
> that bill.
>


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.

I'm just interested in learning different techniques of performing the same
task, just to improve my toolbox

Thanks!
/Carl

>
> --
> Cheers,
> Robbie Hatley
> Tustin, CA, USA
> email: lonewolfintj at pacbell dot net
> web: home dot pacbell dot net slant earnur slant
>
>
>
>
>
>
>
>
>
>
> ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet

News==----
> http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000

Newsgroups
> ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption

=---


 
Reply With Quote
 
Mark A. Gibbs
Guest
Posts: n/a
 
      07-03-2004

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


 
Reply With Quote
 
Carl Ribbegaardh
Guest
Posts: n/a
 
      07-03-2004

"Mark A. Gibbs" <(E-Mail Removed)_x> wrote in message
news:aqzFc.3242$(E-Mail Removed) e.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


 
Reply With Quote
 
Mark A. Gibbs
Guest
Posts: n/a
 
      07-03-2004

Carl Ribbegaardh wrote:

> 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.


thank you, and don't worry, i was aware i was replying two steps removed
when i was harping about the dangers of macros. sorry if i gave the
impression otherwise.

mark

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
BGP alternatives? SP Cisco 3 09-08-2009 02:32 AM
LEAP & ACS Alternatives N. Hall Cisco 2 05-28-2005 08:31 AM
MS Press 2003 books and alternatives Bill Bixby MCSE 7 04-29-2004 05:52 PM
alternatives to accessing PIX via Telnet Anne Robynn Cisco 3 01-03-2004 08:48 AM
Alternatives when user's browser doesn't accept cookies Robert V. Hanson ASP .Net 2 07-03-2003 03:24 AM



Advertisments