468,733 Members | 1,452 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,733 developers. It's quick & easy.

Alternatives to #define?

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
Jul 22 '05 #1
14 3601

"Carl Ribbegaardh" <ca*********************@hotmail.com> wrote in message
news:2k************@uni-berlin.de...
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
Jul 22 '05 #2

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2k************@uni-berlin.de...

"Carl Ribbegaardh" <ca*********************@hotmail.com> wrote in message
news:2k************@uni-berlin.de...
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! :)
Jul 22 '05 #3

"Carl Ribbegaardh" <ca*****************************************@hotma il.com>
wrote in message news:2k************@uni-berlin.de...

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2k************@uni-berlin.de...

"Carl Ribbegaardh" <ca*********************@hotmail.com> wrote in message news:2k************@uni-berlin.de...
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
Jul 22 '05 #4
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.

Jul 22 '05 #5
"Carl Ribbegaardh" <ca*********************@hotmail.com> 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 =---
Jul 22 '05 #6
"Robbie Hatley" <lonewolfintj at pacbell dot net> wrote in message
news:40********@127.0.0.1...
"Carl Ribbegaardh" <ca*********************@hotmail.com> 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

=---
Jul 22 '05 #7

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
Jul 22 '05 #8
* Rolf Magnus:
Alf P. Steinbach wrote:
* Rolf Magnus:
Alf P. Steinbach wrote:

> * Rolf Magnus:
>>
>> #define DO_STUFF do { doThis(); doThat(); } while(false)
>
> Unfortunately that may cause a warning with too "helpful" compilers
> such as Visual C++.
>
> Try instead
>
> #define DO_STUFF for(;;){ doThis; doThat(); break; }

Hmm, what would you gain with that for loop?


See above.


No, I mean what you gain compared to just:

#define DO_STUFF() { doThis(); doThat(); }


Uhm, see my reply to Rob Williscroft. I was wrong. And the extreme
irony is that I've always used do-while for such things precisely
because a simple block won't do wrt. semicolon syntax, and done my best
to teach that technique to others (since you can read Norwegian as well
as C++ code I can offer an example of such teaching, namely the XASSERT
macro in <url: http://home.no.net/dubjai/03/index.html#cpputil>,
presumably some Googling on newsgroup posting would give more examples).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #9
"Mark A. Gibbs" <x_*********@rogesr.com_x> wrote in message
news:rq**************@news04.bloor.is.net.cable.ro gers.com...

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


One more question on the subject:

Why is (for example) SUCCEEDED and FAILED (in winerror.h) implemented as
macros?
...and other stuff that's common like SAFE_DELETE and so on...

Is it just done by habit, or are there any other reason for not using inline
functions?

:)
/Carl
Jul 22 '05 #10
Robbie Hatley wrote:
"Carl Ribbegaardh" <ca*********************@hotmail.com> wrote:

#define DO_STUFF doThis(); doThat();

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


It's dangerous, though. What if you have code like:

if (condition)
DO_STUFF
else
do_something_else();

This won't expand properly. You should write the macro as:

#define DO_STUFF {doThis(); doThat();}

but IMO using an inlined function would be better.

--
Mike Smith
Jul 22 '05 #11
On Mon, 05 Jul 2004 12:13:55 +0200, Carl Ribbegaardh wrote:
"Mark A. Gibbs" <x_*********@rogesr.com_x> wrote in message
news:rq**************@news04.bloor.is.net.cable.ro gers.com...


One more question on the subject:

Why is (for example) SUCCEEDED and FAILED (in winerror.h) implemented as
macros?
..and other stuff that's common like SAFE_DELETE and so on...

Is it just done by habit, or are there any other reason for not using inline
functions?


The standard windows headers can be used in either C or C++ programs. And
inline functions are a C++-only nicety...

- Jay

Jul 22 '05 #12
Jay Nabonne wrote:
On Mon, 05 Jul 2004 12:13:55 +0200, Carl Ribbegaardh wrote:
"Mark A. Gibbs" <x_*********@rogesr.com_x> wrote in message
news:rq**************@news04.bloor.is.net.cable.ro gers.com...


One more question on the subject:

Why is (for example) SUCCEEDED and FAILED (in winerror.h) implemented
as macros?
..and other stuff that's common like SAFE_DELETE and so on...

Is it just done by habit, or are there any other reason for not using
inline functions?


The standard windows headers can be used in either C or C++ programs.
And inline functions are a C++-only nicety...


That's not true. ISO C has been knowing the inline keyword for 5 years
now, and many C compilers have been supporting it for a much longer
time. The windows headers have never been ISO compliant anyway, so they
could have used inline, too.

Jul 22 '05 #13
On Thu, 08 Jul 2004 11:12:18 +0200, Rolf Magnus wrote:
Jay Nabonne wrote:
On Mon, 05 Jul 2004 12:13:55 +0200, Carl Ribbegaardh wrote:
"Mark A. Gibbs" <x_*********@rogesr.com_x> wrote in message
news:rq**************@news04.bloor.is.net.cable.ro gers.com...
One more question on the subject:

Why is (for example) SUCCEEDED and FAILED (in winerror.h) implemented
as macros?
..and other stuff that's common like SAFE_DELETE and so on...

Is it just done by habit, or are there any other reason for not using
inline functions?


The standard windows headers can be used in either C or C++ programs.
And inline functions are a C++-only nicety...


That's not true. ISO C has been knowing the inline keyword for 5 years
now, and many C compilers have been supporting it for a much longer
time. The windows headers have never been ISO compliant anyway, so they
could have used inline, too.


I had a feeling someone would object to that.

How about this replacement for my last line then: at the time that the
Windows header files were developed (> 5 years ago), C compilers (in
particular the Microsoft C compiler) didn't support inline functions.

Does that sit well enough? :)

- Jay

Jul 22 '05 #14
"Jay Nabonne" <ja*@rightagainBYTEME.com> wrote in message
news:pa***************************@rightagainBYTEM E.com...
On Thu, 08 Jul 2004 11:12:18 +0200, Rolf Magnus wrote:
Jay Nabonne wrote:
On Mon, 05 Jul 2004 12:13:55 +0200, Carl Ribbegaardh wrote:

"Mark A. Gibbs" <x_*********@rogesr.com_x> wrote in message
news:rq**************@news04.bloor.is.net.cable.ro gers.com...
>

One more question on the subject:

Why is (for example) SUCCEEDED and FAILED (in winerror.h) implemented
as macros?
..and other stuff that's common like SAFE_DELETE and so on...

Is it just done by habit, or are there any other reason for not using
inline functions?
The standard windows headers can be used in either C or C++ programs.
And inline functions are a C++-only nicety...


That's not true. ISO C has been knowing the inline keyword for 5 years
now, and many C compilers have been supporting it for a much longer
time. The windows headers have never been ISO compliant anyway, so they
could have used inline, too.


I had a feeling someone would object to that.

How about this replacement for my last line then: at the time that the
Windows header files were developed (> 5 years ago), C compilers (in
particular the Microsoft C compiler) didn't support inline functions.

Does that sit well enough? :)

- Jay


Now I understand better why the API's looks like they do. Thanks a lot! :-D

/Carl
Jul 22 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Simon Elliott | last post: by
2 posts views Thread by Michael | last post: by
reply views Thread by Imre | last post: by
43 posts views Thread by Steven T. Hatton | last post: by
1 post views Thread by Doug | last post: by
4 posts views Thread by sunderjs | last post: by
reply views Thread by howa | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
xarzu
2 posts views Thread by xarzu | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.