Cool macro tricks
Hehe, good one. Let''s see:
Not too original though
#define WIN32_LEAN_AND_MEAN#define DIRECTINPUT_VERSION 0x0800#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)#define MSG_ERR(x) MessageBox(NULL, x, "Error!", MB_OK | MB_ICONSTOP)#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)#define ABS(a) (((a)<0) ? -(a) : (a))#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
Not too original though
#define BINOUT(num,cast) {for(long n=sizeof(cast)*8;n--;cout<<!!(num&((cast)0x1<<n)));cout<<flush;}long a=10;BINOUT(a,char) -> 00001010BINOUT(a,long) -> 00000000000000000000000000001010
Was pretty usefull when debuging a small CRC application =)
[edited by - Wildfire on August 19, 2003 3:20:33 PM]
quote:#define ABS(a) (((a)<0) ? -(a) : (a))#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
These macros are very dangerous. Consider:
#define ABS(a) (((a)<0) ? -(a) : (a))#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)int func(int arg){ return ABS(++arg);}int main(int argc, char** argv){ printf("func(5) is %d\n", func(5)); printf("func(-10) is %d\n", func(-10)); return 0;}
You are probably expecting each call to return 6 and 9, but they don''t. Why? The macro''s argument is inserted in the expansion every time the argument''s name (a) appears, and in this case is evaluated twice:
(((++arg)<0) ? -(++arg) : (++arg))
The argument is pre-incremented once during the comparison to zero, and once for either part of the conditional operator. They end up returning 7 and 8 respectively.
You can certainly go ahead and use macros like this all you want, but be very aware that they may have unintended side effects, and the programmer who follows in your footsteps (that''s you in six months) could get tripped up by it, even if you''re aware enough of it now to avoid problems.
If the macro were re-implemented as a regular (or inline) function, the pre-increment would be evaluated before the function is called, and would only happen once.
- dorix
I use this simple macro:
#define CLASSNAME(className) virtual const char *GetCassName() { return #className; }
It just adds virtual funtion to class that returns the class name. I use it in error messages.
class Test
{
public:
CLASSNAME(Test)
};
#define CLASSNAME(className) virtual const char *GetCassName() { return #className; }
It just adds virtual funtion to class that returns the class name. I use it in error messages.
class Test
{
public:
CLASSNAME(Test)
};
the # operator in the preprocessor is great for debugging. I use this little thing all the time
#define dump(x) std::cout << #x ": " << x
Not unusual, but very handy.
#define dump(x) std::cout << #x ": " << x
Not unusual, but very handy.
quote:Original post by stefu
I use this simple macro:
#define CLASSNAME(className) virtual const char *GetCassName() { return #className; }
It just adds virtual funtion to class that returns the class name. I use it in error messages.
class Test
{
public:
CLASSNAME(Test)
};
You could change that to this to write less code:
#define CLASS(className) class className { \public: \virtual const char * GetClassName() {return #className; } \private:
It might not be as nice though
And I need to get a gnuwin32 grep...
for real great macro (and other coding) tricks, you can read up on the ASSERT statement that got set up on .. cuj i think.. or how ever.. of one of the c++ gurus and some other duded..
there, macros get used for real fun things!
"take a look around" - limp bizkit
www.google.com
there, macros get used for real fun things!
"take a look around" - limp bizkit
www.google.com
Here's something for you:
Note: Must be compiled with a C compiler (for VC++: File name must be .c, not .cpp), otherwise it doesn't work.
[edited by - Wildfire on August 19, 2003 4:07:09 PM]
main(t,_,a)char *a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94,-27+t, a)&&t == 2 ?_<13 ?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main(_,t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/"):t<-50?_==*a ?putchar(a[31]):main(-65,_,a+1):main((*a == '/')+t,_,a+1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}
Note: Must be compiled with a C compiler (for VC++: File name must be .c, not .cpp), otherwise it doesn't work.
[edited by - Wildfire on August 19, 2003 4:07:09 PM]
I found a really weird macro in one of the DirectX SDK examples. I think it was the 3d text one.
On a bunch of strings, the code had something like: _T("string here")
So using Visual Assist, I checked what _T was:
#define _T(x) __T(x)
Okay, so I checked what __T was
#define __T(x) x
O________________________O
On a bunch of strings, the code had something like: _T("string here")
So using Visual Assist, I checked what _T was:
#define _T(x) __T(x)
Okay, so I checked what __T was
#define __T(x) x
O________________________O
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement