assert() und Templates



  • Folgendes Konstrukt wirft eine Warnung unter MSVC-2013:

    template<int ME, int YOU>
    inline bool IsKBNK(const Position& p) {
      return true;
    }
    
    template<int ME, int YOU>
    int EvalKBNK(const Position& p) {
      assert(IsKBNK<ME, YOU>(p));
      return 0;
    }
    

    warning C4002: Zu viele übergebene Parameter für das Makro 'assert'

    Habe mir mal die Definition von assert() im Release Modus angesehen:

    #define assert(_Expression)     ((void)0)
    

    Liegt das Problem in der Makroexpansion des Templates IsKBNK<>()?

    Im Debug Betrieb kracht es:

    #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
    

    😕


  • Mod

    Du übergibst an das Makro assert zwei Argumente: IsKBNK<ME und YOU>(p) .
    Am Besten du lagerst den Funktionsaufruf aus:

    bool isKBNK = IsKBNK<ME, YOU>(p);
    assert(isKBNK);
    


  • Arcoth schrieb:

    Du übergibst an das Makro assert zwei Argumente: IsKBNK<ME und YOU>(p) .

    ...was daran liegt, dass Makros kein C++ können und somit die Templatesyntax nicht kennen.



  • assert((IsKBNK<ME, YOU>(p)));
    

    sollte es auch tun.



  • Stimmt, bei der Übergabe von nur einem Template-Argument kompiliert es anstandslos.

    Danke!


  • Mod

    Andere Lösung:

    assert((IsKBNK<ME, YOU>(p))); // Edit: Die Lösung kam zu spät.
    

    Oder ein kleiner Trick, pack das in eine Headerdatei:

    inline void bassert( bool b )
    {
        assert(b);
    }
    

    (alles ungetestet)



  • TyRoXx schrieb:

    assert((IsKBNK<ME, YOU>(p)));
    

    sollte es auch tun.

    nein.



  • oh, ich habs eben getestet mit dem onlinecompiler und die lösung mit den klammern geht überraschenderweise. nehme meine aussage oben zurück.



  • Arcoth schrieb:

    Oder ein kleiner Trick, pack das in eine Headerdatei:

    inline void bassert( bool b )
    {
        assert(b);
    }
    

    (alles ungetestet)

    Man verliert die Fileinformationen (die viele Compiler hilfreiche anfügen), wo das assert fehlgeschlagen ist.



  • Arcoth schrieb:

    Oder ein kleiner Trick, pack das in eine Headerdatei:

    inline void bassert( bool b )
    {
        assert(b);
    }
    

    Damit wirfst du aber viele nette Features von assert über Bord, z.B. die Ausgabe des Fehler-Ausdrucks und der Codezeile. Es hat schon einen Grund, wieso assert ein Makro ist...



  • Dann bleiben nur zwei vernünftige Lösungen übrig:

    assert((IsKBNK<ME, YOU>(p)));
    

    oder

    assert((IsKBNK<ME>(p)));
    

    ... und YOU parametrisieren.

    bool temp = IsKBNK<ME, YOU>(p);
    assert(temp);
    

    wäre auch nicht optimal, da im Release Modus aktiv (Ich meide #ifdefs im Code, wenn möglich).


  • Mod

    Man verliert die Fileinformationen (die viele Compiler hilfreiche anfügen), wo das assert fehlgeschlagen ist.

    Ganz vergessen, tut mir Leid. Schlecht geschlafen, ihr versteht. 💡

    Na gut:

    #define vassert(...) assert((__VA_ARGS__))
    


  • asfsdas schrieb:

    oh, ich habs eben getestet mit dem onlinecompiler und die lösung mit den klammern geht überraschenderweise. nehme meine aussage oben zurück.

    Mich überrascht dass es dich überrascht.
    Wieso sollte es nicht gehen? Klar geht das.


Anmelden zum Antworten