#define Makros mit Body?



  • Mir ist gerade aufgefallen, dass mir nicht klar ist, wie z.B. Boost test Makros definiert, die einen Body haben können:

    BOOST_AUTO_TEST_CASE(test_call)
    {
       BOOST_CHECK(1==1);
    }
    

    Ich hab versucht die Define auflösung anzugucken, werde aber nicht schlau draus.
    Ist es möglich einen Code Body in Makros, so wie oben zu verpacken (muss ja, weils geht 😃 ? Oder wird das innere irgendwie aufgelöst?



  • Einfaches, aber sinnloses Beispiel:

    #include <iostream>
    
    #define LOOP(name,limit) for(int name = 0; name < limit; ++name)
    
    int main()
    {
        LOOP(i, 10)
        {
            std::cout << i;
        }
    }
    


  • #define BOOST_AUTO_TEST_CASE(cases) if((globalcasemask|cases)!=0)
    #define BOOST_CHECK(condition) assert(consition)
    

    würde ja schon reichen.



  • Ja, aber BOOST_AUTO_TEST_CASE macht ne Ecke mehr, es registriert beleibig viele Test Cases in einer Suite und dient als main ersatz, kann dabei jedoch beliebig oft vorkommen



  • Seikilos schrieb:

    Ja, aber BOOST_AUTO_TEST_CASE macht ne Ecke mehr, es registriert beleibig viele Test Cases in einer Suite und dient als main ersatz, kann dabei jedoch beliebig oft vorkommen

    Mal schaun, ob ich sowas auch kann...

    //.h
    #define BOOST_AUTO_TEST_CASE(funktionsname) \
    void funktionsname(); \
    namespace { bool dummy=registerCase(#funktionsname,&funktionsname); } \
    inline void funktionsname()
    

    nebst

    //.cpp
    std::map<std::string,void(*)()> tests;
    bool registerCase(char const* name,void(*f)())
    {
       tests[name]=f;
       return true;
    }
    

    nebst

    extern std::map<std::string,void(*)()> tests;
    int main()
    {
       for each name,func in tests
       {
          cout<<"testing "<<name<<"...\n";
          (*f)();
       }
    }
    


  • Ahhh, das sieht einleuchtend aus, also es wirkt auf jeden Fall einleuchtender, als der Sourc von Boost. Danke!



  • Im folgenden kriegt man das markierte nicht durch ein einziges makro extrahiert, oder? Da muss sowas wie MACRO_ANFANG und MACRO_ENDE gesetzt werden.

    while(condition)
    {
      if(foo)
      { 
        mach was
      }
      else
      {
        //Markierung
      }
    }
    
    MACRO()
    {
      // Markierung
    }
    
    wobei
    #define MACRO() while(condition) ... ist
    

    Würde nicht gehen, weil die letzte geschweifte Klammer nicht mitgenommen wird, richtig?
    Geht das nur über ein zweites Macro oder über ein ziemlich häßliches

    MACRO()
    {
      // Markierung
    }
    }
    

    Ich will es so einfach wie möglich halten und nicht so etwas wie anonyme funktionen oder delegaten benutzen



  • Seikilos schrieb:

    Im folgenden kriegt man das markierte nicht durch ein einziges makro extrahiert, oder? Da muss sowas wie MACRO_ANFANG und MACRO_ENDE gesetzt werden.

    while(condition)
    {
      if(foo)
      { 
        mach was
      }
      else
      {
        //Markierung
      }
    }
    

    wobei
    #define MACRO() while(condition) ... ist[/cpp]

    #define MACRO(condition) \
    while (condition)        \
     if (!foo || (machwas(), false))
    
    int bar()
    {
      int i = 0;
      MACRO(i != 10)
      {
        ++i;
      }
    }[cpp]
    
    wird zu 
    [cpp]
    int bar()
    {
      int i = 0;
      while(i != 10)
        if(!foo || (machwas(), false))
        {
          ++i;
        }
    }
    

    falls !foo ergibt, wird die zweite Bedingung des op|| nicht ausgewertet und ++i ausgeführt.
    falls foo true ist, ergibt !foo false, es wird (machwas(), false) ausgewertet,also machwas() ausgeführt und false zurückgegeben.
    Sowas ist aber böse Makro-Hackerei und kann auch anderweitig erledigt werden.



  • Seikilos schrieb:

    Im folgenden kriegt man das markierte nicht durch ein einziges makro extrahiert, oder? Da muss sowas wie MACRO_ANFANG und MACRO_ENDE gesetzt werden.

    while(condition)
    {
      if(foo)
      { 
        mach was
      }
      else
      {
        //Markierung
      }
    }
    

    Entweder BEGIN/END oder schwarzes Hacken oder Erkennen, daß die äußeren Klammern total nutzlos waren. :p

    while(condition)
      if(foo)
      { 
        mach was
      }
      else
      {
        //Markierung
      }
    


  • Ist ja nur ein beispiel. Die sitation ist schon so, das dort noch mehr befehle außerhalb der ifs gekapselt sind


Anmelden zum Antworten