|
-
November 25th, 2002, 03:12 PM
#1
Macros
can i make a macro return a value ??
something like this..
#define int A_MACRO(X) If (X==1) return 2 \
else return 1;
Thanks in Advance
-
November 25th, 2002, 03:22 PM
#2
No. Macros are not functions. Check this by directly substiting this macro in place where it's used. It's probably not what you want.
You'd be better off avoiding macros altogether, but the following might be more what you want:
Code:
#define A_MACRO(X) ((X) == 1 ? 2 : 1)
Jeff
-
November 25th, 2002, 03:29 PM
#3
Thank You Jeff. That was helpful!
-
November 25th, 2002, 03:33 PM
#4
If you absolutely had to "return" a value from a macro you can
set one of the macro parameters to a value. As jfaust said,
better to avoid macros if you can. They lack type checking
and can easily produce unintended results.
regards, willchop
-
November 26th, 2002, 12:36 AM
#5
better off avoiding macros altogether
Hmmm... sounds a bit like "better off avoiding goto altogether!" Personally, I think each has it's place:
Want to jump out of multiple while, for, switch statements? A goto is ok.
Want to hide __LINE__ or __FILE__ inside some statement (like ASSERT() )? Use a macro.
Also... want to use C where templates and inline statements do not exist? Use a macro.
Yes, macros has less typechecking than templates, but as with almost anything... with flexibility comes responsibility.
- Kevin
-
November 26th, 2002, 12:55 AM
#6
Oh, and you can always do something like this when you need to return the value of some function call that takes place in the middle of your macro -- granted this method requires a global variable, *and I DO recommend you try to find some other way to accomplish what you want* but sometime this makes sense:
#include <stdio.h>
int sq(int x)
{
return x*x;
}
int z;
#define CUBE(x) ( z = x*sq(x), printf("In a macro\n"), 1 ? z : 0 )
void main()
{
printf("3 cubed = %d\n", CUBE(3));
}
The key point is that you need to have:
",1 ? <return value> : <value that never gets used>"
Hope this helps,
Kevin
-
November 26th, 2002, 01:21 AM
#7
Hmmm... sounds a bit like "better off avoiding goto altogether!"
Well, I won't beat a dead horse except to say... "exactly."
There are rare cases when macros solve a problem better, but there's almost always a better alternative.
Same with goto, although I've seen no example where goto helps anything.
Jeff
-
November 26th, 2002, 02:06 AM
#8
Consider C, where there is no exception handling:
for ( ; ; )
{
int finished = 0; /* false */
do
{
switch (someCase)
{
case 1: finished = 1; /* exit outer loop */
break;
case 2: /* other stuff */
}
if (finished != 0) break;
} while (someCondition);
if (finished != 0) break;
}
OR
for ( ; ; )
{
do
{
switch (someCase)
{
case 1: goto outsideLoops; /* exit outer loop */
case 2: /* other stuff */
}
} while (someCondition);
}
outsideLoops:
/* continue with program */
Last edited by KevinHall; November 26th, 2002 at 02:09 AM.
-
November 26th, 2002, 02:22 AM
#9
I should stress that I do recommend avoiding gotos and macros -- if for no other reason because your boss, coworkers, or customers will view your work as unprofessional . Seriously, I really have seen this happen. But as I believe (and I know this has been debated many, many times before) that the above example is one place where a goto makes sense. Usually, there is a good reason why something was implemented, and I am weary of saying that it should be *totally* abandonned.
!!!NOTE!!!: I have never found a place in C++ code where goto cannot and should not be replaced (not to say one doesn't exist). goto's are inherently dangerous in C++ because among other things destructors do not get called. In C++ it's very easy to jump out of a block of code while still calling destructors by using try/catch. I have only used gotos in C.
-
November 26th, 2002, 02:44 AM
#10
macros and gotos
It seems that every few weeks lately these two issues have popped up. There was a great, impassioned goto thread recently. At the time, I found myself beat by the "goto is not connected to the logic of the branch" argument. However, I have recently doubted that this could be a final argument, since that would mean abandoning break, continue, and generally a goto is just a in-block function call with no parameters and is no more difficult to understand than a true function call except for the lack of return. In fact, this may be one of the unexplored strengths of goto, that it may be used to generalize the function concept in a powerful way, giving one control over the separate tasks of call and return (though this has only occurred to me about a week ago, and I have no real idiom as of yet).
Similarly, with macros, I use them for organizing repetitive tasks like arrays where I want to enforce a naming convention. For example, if I want to make a struct that holds a string "functionname", a function pointer to my own superfunctionname, and some associated members that are named after the original function name, I use a macro because of its string manipulating abilities. Similarly, there are some great uses for macros in automating TypeList declarations and many other uses in "preprocessor metaprogramming" such as that found in the boost libraries.
These are truly debatable issues with much to be sorted out. One point to note, though, is that I believe gotos do call destructors.
*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
"It's hard to believe in something you don't understand." -- the sidhi X-files episode
galathaea: prankster, fablist, magician, liar
-
November 26th, 2002, 02:51 AM
#11
Check out this maelstrom of opinions for the battle over goto.
*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
"It's hard to believe in something you don't understand." -- the sidhi X-files episode
galathaea: prankster, fablist, magician, liar
-
November 26th, 2002, 07:18 AM
#12
Re: macros and gotos
Originally posted by galathaea
These are truly debatable issues with much to be sorted out. One point to note, though, is that I believe gotos do call destructors.
I believe that you are right about this as well. It's my
understanding that nonlocal goto's cause destructors to not be
called ... well at least that's what the standard says about them.
Non-local goto's are created by setjump() & longjump(); the goto
keyword is considered a "local goto".
--Paul
-
November 26th, 2002, 10:12 AM
#13
Well, I compiled and ran this program below:
#include <iostream>
using namespace std;
struct MyStruct
{
MyStruct() {cout << "In constructor" << endl;}
~MyStruct() {cout << "In destructor" << endl;}
};
void main()
{
int i;
for (i=0;;++i)
{
MyStruct ms;
if (i == 1) goto endMain;
}
endMain:
cout << "Exiting program" << endl;
}
And the constructor does get called (In MSVC6).... I could swear I read somewhere that it didn't. Hmmm....
Paul, C/C++ doesn't allow gotos outside of the currently defined function. If by non-local goto, you mean a longjmp, well there are several issues with that -- only one of them being destructors not being called.
Thanks for helping clear things up!
- Kevin
-
November 26th, 2002, 11:16 AM
#14
Originally posted by KevinHall
Paul, C/C++ doesn't allow gotos outside of the currently defined function. If by non-local goto, you mean a longjmp, well there are several issues with that -- only one of them being destructors not being called.
Yeah I meant longjmp(). I'm sorry; I always type them out as
setjump and longjump ... dang unnecessary u's.
-
November 26th, 2002, 11:59 AM
#15
*********************************************
There are rare cases when macros solve a problem better, but there's almost always a better alternative.
*********************************************
Macro's are unique in the phylum of C/C++ programming. Anybody who would equate them with const variables is trying to substitute a slice of pizza for an entire pie.
First off const variables can be recast and overwritten which makes them an imperfect alternative when writing libraries for third parties.
Second off and this is a biggie, all would be macro pretenders get interpreted at run time while macro's get interpreted at compile time. This functionality gives programming with macro's incredible functionality, which cannot be replaced with variables.
For example.. The ANSI C/C++ macro’s, which come with all compilers __LINE__ and __FILE__ which respectively return the line number of the calling code file and a string containing the name of the code file. Now if one writes a simple little macro, which puts these, two jewels together...
#define LOG(X) PutItInAFile( (X), __FILE__, __LINE__ )
where
PutItInAFile is a function..
int PutItInAFile( char *pszMsg, char *pszFileName, long lLine);
Now one can put the little macro in one's code like this...
if ( NULL == ( pFoo = new MYFOO))
(
LOG ( "Memory Allocation Failed" );
)
Now your calling log file has not only a timestamp of when an error occurred but also the calling file and the line number of the error. Life without macro's is like a life without color or spice..
**********************************************
your boss, coworkers, or customers will view your work as unprofessional . Seriously, I really have seen this happen.
**********************************************
I know it's true, but it's also true that I've been told the following pearls of wisdom in code reviews....
1- Don't use "void *"'s cause they're ambiguous!!!
2- Either increment loops or decrement loops in your application but don't use both cause they make it hard to read.. Be consistent..
3- Don’t compile your code to find syntax errors, you should be able to eyeball code for that purpose. Since Eastern European software developers make fewer programming and logic errors adhering to this tactic we've actually decided to not provide our developers with compilers!!
Anybody who would tell you that macro's are unprofessional is a person who doesn't understand what they're used for... such absolutism is a totem of mediocrity..
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|