constexpr, static_assert und inlining

Ich habe vorher nachgefragtFunktionsüberladung basierend darauf, ob die Argumente sindconstexpr. Ich versuche, die enttäuschende Antwort auf diese Frage zu umgehen, um eine intelligentere Assert-Funktion zu erzielen. Das ist ungefähr das, was ich versuche zu tun:

<code>inline void smart_assert (bool condition) {
    if (is_constexpr (condition))
        static_assert (condition, "Error!!!");
    else
        assert (condition);
}
</code>

Grundsätzlich ist die Idee, dass eine Überprüfung zur Kompilierungszeit immer besser ist als eine Laufzeitüberprüfung, wenn es möglich ist, eine Überprüfung zur Kompilierungszeit durchzuführen. Aufgrund von Inlining und konstantem Falzen kann ich jedoch nicht immer wissen, ob eine Überprüfung der Kompilierungszeit möglich ist. Dies bedeutet, dass es Fälle geben kann, in denenassert (condition) kompiliert bis aufassert(false) und der Code wartet nur darauf, dass ich ihn ausführe und diesen Pfad ausführe, bevor ich herausfinde, dass ein Fehler vorliegt.

Wenn es also eine Möglichkeit gäbe, zu überprüfen, ob die Bedingung ein Constexpr ist (aufgrund von Inlining oder anderen Optimierungen), könnte ich anrufenstatic_assert wenn möglich, und greifen Sie auf eine Laufzeit zurück, wenn dies nicht der Fall ist. Zum Glück hat gcc das Wesentliche__builtin_constant_p (exp), was true zurückgibt, wennexp ist ein constexpr. Ich weiß nicht, ob andere Compiler diese Eigenheiten haben, aber ich hatte gehofft, dass dies mein Problem lösen würde. Dies ist der Code, den ich mir ausgedacht habe:

<code>#include <cassert>
#undef IS_CONSTEXPR

#if defined __GNUC__
    #define IS_CONSTEXPR(exp) __builtin_constant_p (exp)
#else
    #define IS_CONSTEXPR(exp) false
#endif
// TODO: Add other compilers

inline void smart_assert (bool const condition) { 
    static_assert (!IS_CONSTEXPR(condition) or condition, "Error!!!");
    if (!IS_CONSTEXPR(condition))
        assert (condition);
}

#undef IS_CONSTEXPR
</code>

Dasstatic_assert setzt auf das Kurzschlussverhalten vonor. ObIS_CONSTEXPR ist also wahrstatic_assert kann verwendet werden, und die Bedingung ist!true or condition, das ist das gleiche wie geradecondition. ObIS_CONSTEXPR ist also falschstatic_assert kann nicht verwendet werden, und die Bedingung ist!false or condition, das ist genauso wietrue und dasstatic_assert wird ignoriert. Wenn dasstatic_assert kann nicht überprüft werden, weilcondition ist kein constexpr, dann füge ich eine laufzeit hinzuassert zu meinem Code als letzter Versuch. Dies funktioniert jedoch nicht dankFunktionsargumente in a nicht verwenden könnenstatic_assert, auch wenn die Argumente sindconstexpr.

Dies passiert insbesondere, wenn ich versuche, mit gcc zu kompilieren:

<code>// main.cpp
int main () {
    smart_assert (false);
    return 0;
}
</code>

g++ main.cpp -std=c++0x -O0

Alles ist in Ordnung, wird normal kompiliert. Es gibt also kein Inlining ohne OptimierungIS_CONSTEXPR ist falsch und diestatic_assert wird ignoriert, also bekomme ich nur eine laufzeitassert Anweisung (die fehlschlägt). Jedoch,

<code>[david@david-desktop test]$ g++ main.cpp -std=c++0x -O1
In file included from main.cpp:1:0:
smart_assert.hpp: In function ‘void smart_assert(bool)’:
smart_assert.hpp:12:3: error: non-constant condition for static assertion
smart_assert.hpp:12:3: error: ‘condition’ is not a constant expression
</code>

Sobald ich Optimierungen einschalte und damit eventuell zulassestatic_assert ausgelöst zu werden, schlägt fehl, weil ich keine Funktionsargumente in derstatic_assert. Gibt es eine Möglichkeit, dies zu umgehen (auch wenn es bedeutet, meine eigene zu implementieren?static_assert)? Ich bin der Meinung, dass meine C ++ - Projekte theoretisch einiges von einer intelligenteren Aussage profitieren könnten, die Fehler so früh wie möglich erkennt.

Es scheint nicht zu machensmart_assert Ein funktionsähnliches Makro löst das Problem im allgemeinen Fall. Es wird natürlich in diesem einfachen Beispiel funktionieren, abercondition Möglicherweise stammt eine Funktion aus einer zwei Ebenen höheren Aufrufgrafik (wird dem Compiler jedoch immer noch als eine bekanntconstexpr aufgrund von Inlining), bei dem das gleiche Problem auftritt wie bei der Verwendung eines Funktionsparameters in astatic_assert.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage