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
Printable View
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
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:
JeffCode:#define A_MACRO(X) ((X) == 1 ? 2 : 1)
Thank You Jeff. That was helpful!
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
Hmmm... sounds a bit like "better off avoiding goto altogether!" Personally, I think each has it's place:Quote:
better off avoiding macros altogether
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
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
Well, I won't beat a dead horse except to say... "exactly."Quote:
Hmmm... sounds a bit like "better off avoiding goto altogether!"
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
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 */
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.
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.
Check out this maelstrom of opinions for the battle over goto.
I believe that you are right about this as well. It's myQuote:
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.
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
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
Yeah I meant longjmp(). I'm sorry; I always type them out asQuote:
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.
setjump and longjump ... dang unnecessary u's.
*********************************************
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..