Ich habe mehrere constexpr-Funktionen geschrieben und verwende sie in static_asserts, um einige Ressourcenlimits zu steuern. Aber ich möchte nicht nur das Kompilierungszeitprädikat erzwingen, sondern auch die tatsächlichen Werte sehen, die während des normalen Kompilierungsprozesses berechnet wurden oder zumindest, wenn die Assertion fehlschlägt.
Es gibt Möglichkeiten, String-Nachrichten während der Kompilierung zu drucken, aber was ist mit dem Drucken von Ergebnissen von conexpr-Berechnungen?
Hier ist ein Code, der die Diagnosemeldungen von gcc ausnutzt, um nach einer Assert-Nachricht Werte von Interesse zu drucken. Um die gewünschten Werte zu finden, müssen Sie nur die Fehlerzeichenfolge für T x =
:
Hier ist der Fehler, der es mir gebracht hat:
g++ h.cpp -std=c++11
h.cpp: In instantiation of ‘constexpr void my_assert() [with bool B = false]’:
h.cpp:16:34: required from ‘f() [with int X = 4]::__lambda0::__lambda1’
h.cpp:15:35: required from ‘struct f() [with int X = 4]::__lambda0::__lambda1’
h.cpp:16:38: required from ‘f() [with int X = 4]::__lambda0’
h.cpp:14:28: required from ‘struct f() [with int X = 4]::__lambda0’
h.cpp:16:41: required from ‘void f() [with int X = 4]’
h.cpp:21:10: required from here
h.cpp:9:5: error: static assertion failed: oh no
static_assert(B, "oh no");
^
h.cpp:4:6: error: ‘void transparent(F) [with T = long int; T x = 64l; F = f() [with int X = 4]::__lambda0::__lambda1]’, declared using local type ‘f() [with int X = 4]::__lambda0::__lambda1’, is used but never defined [-fpermissive]
void transparent(F f) { f(); }
^
h.cpp:4:6: error: ‘void transparent(F) [with T = int; T x = 11; F = f() [with int X = 4]::__lambda0]’, declared using local type ‘f() [with int X = 4]::__lambda0’, is used but never defined [-fpermissive]
Beachten Sie, dass fett gedruckte Teile
Mein VC ++ - Code, der während der Kompilierung den Wert von beliebig vielen Kompilierzeitkonstanten (z. B. sizeof structures) ausgibt und das Kompilieren ohne Fehler fortsetzt:
%Vor%Beispielausgabe von VC ++ 2010. Der Zielwert ist der erste Funktionsschablonenparameterwert (im Beispiel 0x18 und 0xd8), den VC ++ als hexadezimalen Wert ausgewählt hat !!
%Vor% Die wichtigste Technik, die hier verwendet wird, besteht darin, dass die #pragma message()
-Direktive bei jeder Funktionsvorlageninstanziierung einmal aufgerufen wird. Das Microsoft-spezifische Makro __FUNCSIG__
kann die Signatur der enthaltenden Funktion und somit den Integer-Wert anzeigen, der bei jeder spezifischen Instantiierung der Funktionsvorlage verwendet wird. Wenn COUNTER
als zweiter Vorlagenparameter angegeben wird, wird sichergestellt, dass 2 ganze Zahlen mit demselben Wert immer noch als unterschiedlich angesehen werden. Die 1 in der #pragma
-Direktive ist hier nicht von Nutzen, kann aber als Bezeichner verwendet werden, falls wir mehr als eine solche Direktive haben und das Ausgabefenster voller unordentlicher Nachrichten ist.
Tags und Links c++ gcc c++11 constexpr static-assert