Wie man printf-Stil compile-Zeit Warnungen oder Fehler
Ich würde gerne eine routine zu schreiben, wie bei printf, nicht funktional-Weise, sondern ich möchte die routine, um die gleiche Zeit, kompilieren, überprüfen Eigenschaften wie printf.
Wenn ich beispielsweise habe:
{
int i;
std::string s;
printf("%d %d",i);
printf("%d",s.c_str());
}
Der compiler beschwert sich etwa so:
1 cc1plus: warnings being treated as errors
2 In function 'int main()':
3 Line 8: warning: too few arguments for format
4 Line 9: warning: format '%d' expects type 'int', but argument 2 has type 'const char*'
Sind printf und co spezielle Funktionen, die der compiler behandelt anders, oder gibt es ein trick, um zu bekommen, dies funktioniert auf jeder Benutzer-definierter Funktion? Die spezifischen Compilern, die ich bin daran interessiert, sind gcc und msvc
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verschiedene Compiler implementieren Sie diese Funktionalität anders. Im GCC umgesetzt wird es über
__attribute__
Planer mitformat
Attribut (gelesen hier). Der Grund, warum der compiler führt die überprüfung ist nur, dass in der standard-header-Dateien geliefert, die mit GCC dieprintf
Funktion wird deklariert mit__attribute__((format(printf, 1, 2)))
In genau der gleichen Weise, die Sie verwenden können
format
Attribut zu erweitern, das gleiche format-überprüfung der Funktionalität, um Ihre eigenen variadischen Funktionen, die den gleichen Formatangaben alsprintf
.Dies alles wird nur funktionieren, wenn die parameter-übergabe-Konvention und der format-Spezifizierer, die Sie verwenden, sind die gleichen wie die, die von den standard -
printf
undscanf
Funktionen. Die Prüfungen sind hardcoded in den compiler. Wenn Sie verwenden eine andere Konvention für variadic argument übergeben, wird der compiler dir nicht helfen, um es zu überprüfen.Dieses Verhalten ist höchst compiler abhängig. Ich glaube, dass gcc bietet eine Schnittstelle für die Typprüfung variadischen Funktionen.
printf()
und Freunde sind nicht etwas besonderes, weil Sie akzeptieren eine variable Anzahl von Argumenten: benutzerdefinierte Funktionen akzeptieren eine variable Anzahl von Argumenten zu. Sie sind etwas besonderes, weil Ihr Verhalten ist definiert durch den standard, so dass der compiler weiß, was die Korrelation zwischen format-string und den Argumenten, die der Funktion übergeben.Effektiv der compiler weiß, wie viele Argumente werden an die Funktion übergeben, wenn Sie aufgerufen wird, so wird es analysiert den format-string und vergleicht die voraussichtliche Anzahl und die Typen der Argumente gegen das, was Argumente eigentlich sind, an die Funktion übergeben und gibt eine Warnung, wenn Sie nicht übereinstimmen.
Wenn Sie mit C++, ich möchte vermeiden, schreiben Sie Ihre eigenen variadischen Funktionen; es gibt einige gute Gründe, um Sie in die meisten Projekte. Zum Beispiel, wenn Sie tun, Formatierung, verwenden Sie streams oder eine Bibliothek wie Boost-Format. Jedes problem, das gelöst werden kann mit einer variadischen Funktion können gelöst werden using a non-Variable Funktion, und in fast allen Fällen das Ergebnis ist eleganter, idiomatische und Typ-sicher.
Eigentlich
printf
keine inhärente compile-time Sicherheit aller. Es passiert einfach, dass in einigen neueren Compilern implementiert haben spezielle Prüfungen gegeben, dass Sie genau weiß was für ein format-string bedeutet in Bezug auf die zusätzlichen Parameter. Wenn Sie...
als parameter du sagst, dass Sie möchten, zu akzeptieren beliebige Argumente und übernehmen die volle Verantwortung für die Herstellung sicher, dass Sie korrekt sind. Es gibt keine Möglichkeit, dass der compiler überprüfen Sie Sie für die Anzahl/Art Sicherheit.Anstatt zu versuchen, um den compiler zu helfen, Sie auf diese Weise, versuchen Sie es mit dem Ansatz von standard-streams: nutzen Sie eine (möglicherweise Vorlage) - Funktion oder operator liefert eine Referenz auf
this
zu ermöglichen, aufweist. Dann wird der compiler in der Lage sein, Ihnen zu sagen, sofort, wenn die Argumente nicht mit dem übereinstimmt, was erwartet/unterstützt.Einer Weile jemand geschrieben eine mpl::string boost Gruppen. Ich denke, es kann tatsächlich bekommen haben in die Bibliothek. Wenn das der Fall ist könnte man etwas umsetzen wie diese, indem Sie Ihre Vorlage-Zeichenfolge als ein parameter template angegeben wurde (eine mpl::string) und dann über einige ziemlich tiefgründige meta-Programmierung Fähigkeiten zu analysieren, die Formatierung-bits in ihm. Dann würden Sie diese Informationen benutzen, um wählte eine Umsetzung mit dem entsprechenden argument-Anzahl und Typen.
Nein, ich werde das nicht tun es für Sie 😛 Es würde ziemlich schwierig sein. Allerdings glaube ich das es möglich wäre.