Preprocessor

Discussion in 'C++' started by buchtak@gmail.com, Jul 31, 2009.

  1. Guest

    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?
     
    , Jul 31, 2009
    #1
    1. Advertising

  2. "" <> 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__
     
    Pascal J. Bourguignon, Jul 31, 2009
    #2
    1. Advertising

  3. Guest

    Thx Pascal. I guess that determining whether particular non-
    preprocessor variable exists in the scope, which would elegantly solve
    the problem, is impossible via the preprocessor. The problem with your
    solution is, that the timer couldn't be stopped in an if-block for
    example. I don't know about boost::foreach, but using it in this
    particular case seems to undermine the basic reason of using macros,
    which is to simplify things. But thx anyway for ideas.
     
    , Jul 31, 2009
    #3
  4. James Kanze Guest

    On Jul 31, 2:07 pm, (Pascal J. Bourguignon)
    wrote:
    > "" <> writes:


    > > 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;


    Putting mismatched braces in a macro is a nice trick to render
    the code unreadable. There are very few cases where it is
    justified (although admittedly, this may be one). Why not just
    use a class, which reads the timer in the constructor and the
    destructor? (Presumably, you'll also want to capture the
    results somewhere, so the constructor needs a reference to
    that.)

    Having said that... All his macro gains him is one line, that
    which declares the variable. IMHO, it's not worth it.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Aug 1, 2009
    #4
  5. James Kanze <> writes:

    > On Jul 31, 2:07 pm, (Pascal J. Bourguignon)
    > wrote:
    >> 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;

    >
    > Putting mismatched braces in a macro is a nice trick to render
    > the code unreadable. There are very few cases where it is
    > justified (although admittedly, this may be one). Why not just
    > use a class, which reads the timer in the constructor and the
    > destructor? (Presumably, you'll also want to capture the
    > results somewhere, so the constructor needs a reference to
    > that.)
    >
    > Having said that... All his macro gains him is one line, that
    > which declares the variable. IMHO, it's not worth it.


    Yes, I must admit that if there is only this functionality to abstract
    away, such a couple of macro may be overdoing it. However, the
    technique is still useful in more complex cases.


    Notice that we are not after the line count, but after a syntactic
    abstraction: we want to hide what is inside the macro.


    Sometimes functional abstraction or data abstraction (objects) is
    enough to hide the details, but unfortunately, there are occurences
    where functional abstraction is not enough (for example, when you have
    to remind using try/catch around every occurences of your functional
    abstraction), and were a good macro makes miracle in readability and
    bug avoidance.



    But given the need the OP expressed later, to stop the timer inside
    the body, in his case indeed a RAII pattern would be better.

    try{
    Timer timer(Minute(3));
    doSomethingSlow();
    if(needMoreTime){
    timer.stop();
    doSomethingEvenSlower();
    }
    }catch(Timeout& e){
    notEnoughTimeToCompleteTheTask(e);
    }

    --
    __Pascal Bourguignon__
     
    Pascal J. Bourguignon, Aug 3, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris P
    Replies:
    0
    Views:
    441
    Chris P
    Oct 28, 2003
  2. The Weiss Family

    VHDL Preprocessor

    The Weiss Family, Jul 14, 2004, in forum: VHDL
    Replies:
    2
    Views:
    3,228
    The Weiss Family
    Jul 14, 2004
  3. =?Utf-8?B?SSBhbSBTYW0=?=

    C# Preprocessor

    =?Utf-8?B?SSBhbSBTYW0=?=, Mar 13, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    1,580
    =?Utf-8?B?SSBhbSBTYW0=?=
    Mar 13, 2005
  4. Replies:
    0
    Views:
    2,679
  5. Cronus
    Replies:
    1
    Views:
    676
    Paul Mensonides
    Jul 15, 2004
Loading...

Share This Page