Macros and preprocessor tricks...

Started by
6 comments, last by 3dModelMan 20 years, 5 months ago
As part of a debug logging project, I''m trying to write an "execute once" macro. So far I have;

#define _CRITICAL_ONCE(uid,y)	static int (uid)=0; if((uid)==0){ (y); (uid)++;};
 
Then in the user code;

_CRITICAL_ONCE( iTemp, dbgMsg( "This message is only posted once" ));
 
Is there anyway to automatically define a unique variable name at compile time and avoid the ''uid'' argument? I''m generally learning new macro tricks ATM, so if you have any resources or hints please let me have them - Matt
Advertisement
Scoping is your friend. Try

#define _CRITICAL_ONCE(y) { static int uid=0; if(uid==0){ (y); uid++;}}

instead. The additional braces guarantee that the uid name is only visible /inside/ those braces. That means you can have a gazillion of those, and they all have different scope and never conflict.

- Robert
*doh!* Perfect-- thanks!
Although his solution is more elegant, things like __LINE__ concatenated with something would work too...
Puzzler183; I''ve tried appending __LINE__ to variable names without success, can you show me how it''s done?
In regard to scoping, a do - while(0) - works as well

#define _CRITICAL_ONCE(y) do { static int uid=0; if(uid==0){ (y); uid++;}} while(0)

In regard to using __LINE__ consider,

#define _CRITICAL_ONCE(y) do { static int uid =0; if(uid == 0){ (y); uid = __LINE__;}} while(0)
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
To concatenate __LINE__ and a variable name, use the handy concatenation operator.

#define MAGIC_VARIALBLE uid ## __LINE__
int MAGIC_VARIABLE;

will generate

int uid2;

in case the above lines are 1 and 2 in the source. Of course, the preprocessor is a horrendous evil, but if you have to use it, it''s handy to know the tricks

- Robert
LessBread; The do-while seems redundant when the braces add all the scoping needed in this case. Thanks tho.

groby; That''s what I was looking for. I didn''t realise the whitespace would be removed (and obviously uid##__LINE__ just creates a variable named ''uid__LINE__''). The scoping solved the original problem, this continued interest was just out of curiosity ;-)

Cheers!

This topic is closed to new replies.

Advertisement