Re: Preprocessor
"buchtak@gmail.com" <buchtak@gmail.com> writes:
Hi,
is there a way to test if a variable is defined by a preprocessor
directive? Suppose, for example, I want to simplify this code by using
two macros:
Timer t1;
t1.start();
... // some action
t1.stop();
std::cout << "..." << endl;
#define TIMER_START(x) // defines timer tx and starts timing
#define TIMER_STOP(x) // stops timer tx and prints out the elapsed
time
However, the problem arises when I try to call TIMER_START(1) twice in
the same block since there's redefinition of t1. Is there a way to
extend the TIMER_START(x) macro such that it would first test if the
timer tx exists to avoid compiler errors?
It would be better if you defined a scoping couple of macros.
Assume you want expanded code such as:
{
Timer tXYZ;
try{
tXYZ.start();
[BODY]
tXYZ.stop();
}catch(...){
tXYZ.stop();
throw;
}
}
Then it wouldn't matter if you used the same name in an embedded version:
{
Timer tXYZ;
try{
tXYZ.start();
{
Timer tXYZ;
try{
tXYZ.start();
[BODY]
tXYZ.stop();
}catch(...){
tXYZ.stop();
throw;
}
}
tXYZ.stop();
}catch(...){
tXYZ.stop();
throw;
}
}
you would still have two different timers, and the references to each
are well scoped, lexically.
#define WITH_TIMER_BEGIN(TIMEOUT) \
do{ \
Timer CURRENT_TIMER; \
try{ \
CURRENT_TIMER.start(TIMEOUT); \
{ \
int CURRENT_TIMER=0; /* hides the real timer */
#define END_WITH_TIMER \
} \
CURRENT_TIMER.stop(); \
}catch(...){ \
CURRENT_TIMER.stop(); \
throw; \
} \
}while(0)
and write:
WITH_TIMER_BEGIN(Minute(3)){
do_something_slow();
}END_WITH_TIMER;
WITH_TIMER_BEGIN(Minute(3)){
do_something_slow();
WITH_TIMER_BEGIN(Second(15)){
do_something_not_too_slow();
}END_WITH_TIMER;
do_something_slow();
}END_WITH_TIMER;
(There's also a way to play tricks with for and if to avoid having to
define a END_XYZ macro, see for example boost::foreach, but it's
rather tricky and not always feasible.)
--
__Pascal Bourguignon__