Kann ich zum Zwecke des Debuggens die Zeilennummer in C / C ++ - Compilern abrufen ? (Standardmethode oder spezielle Methoden für bestimmte Compiler)
z.B
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
Antworten:
Sie sollten das Präprozessor-Makro
__LINE__
und verwenden__FILE__
. Sie sind vordefinierte Makros und Teil des C / C ++ - Standards. Während der Vorverarbeitung werden sie jeweils durch eine konstante Zeichenfolge ersetzt, die eine Ganzzahl enthält, die die aktuelle Zeilennummer darstellt, sowie durch den aktuellen Dateinamen.Andere Präprozessorvariablen:
__func__
: Funktionsname (dies ist Teil von C99 , wird nicht von allen C ++ - Compilern unterstützt)__DATE__
: eine Zeichenfolge der Form "Mmm tt jjjj"__TIME__
: eine Zeichenfolge der Form "hh: mm: ss"Ihr Code lautet:
quelle
#define S1(N) #N
#define S2(N) S1(N)
#define LINESTR S2(__LINE__)
. Siehe c-faq.com/ansi/stringize.html__func__
handelt es sich nicht um ein Makro, sondern um eine implizit deklarierte Variable.Als Teil des C ++ - Standards gibt es einige vordefinierte Makros, die Sie verwenden können. Abschnitt 16.8 des C ++ - Standards definiert unter anderem das
__LINE__
Makro.Ihr Code wäre also:
quelle
Sie können ein Makro mit demselben Verhalten wie printf () verwenden , außer dass es auch Debug-Informationen wie Funktionsname, Klasse und Zeilennummer enthält:
Diese Makros sollten sich identisch mit printf () verhalten und Java-Stacktrace-ähnliche Informationen enthalten. Hier ist ein Hauptbeispiel:
Was zu folgender Ausgabe führt:
quelle
#include
to<stdio.h>
Verwenden Sie
__LINE__
(das ist doppelter Unterstrich LINE doppelter Unterstrich), der Präprozessor ersetzt ihn durch die Zeilennummer, auf die er stößt.quelle
Kasse
__FILE__
und__LINE__
Makrosquelle
C ++ 20 bietet eine neue Möglichkeit, dies mithilfe von std :: source_location zu erreichen . Dies ist derzeit in gcc an clang wie
std::experimental::source_location
bei zugänglich#include <experimental/source_location>
.Das Problem bei Makros wie
__LINE__
ist, dass Sie, wenn Sie beispielsweise eine Protokollierungsfunktion erstellen möchten, die die aktuelle Zeilennummer zusammen mit einer Nachricht ausgibt, immer__LINE__
als Funktionsargument übergeben müssen, da diese am Aufrufstandort erweitert wird. Etwas wie das:Gibt immer die Zeile der Funktionsdeklaration aus und nicht die Zeile, in der
log
tatsächlich aufgerufen wurde. Auf der anderen Seite könnenstd::source_location
Sie mit so etwas schreiben:Hier
loc
wird mit der Zeilennummer initialisiert, die auf den Ort zeigt, an demlog
aufgerufen wurde. Sie können es hier online ausprobieren.quelle
Versuchen Sie
__FILE__
und__LINE__
.Sie könnten auch finden
__DATE__
und__TIME__
nützlich.Wenn Sie jedoch kein Programm auf der Clientseite debuggen und daher diese Informationen protokollieren müssen, sollten Sie das normale Debugging verwenden.
quelle
raw code
(wie folgt: \ _ \ _) oder Backticks verwenden, um sie als (wie folgt: `__`) zu markieren . @mmyers versuchte zu helfen, aber er entkam nur einem der Unterstriche, und so blieb Ihnen die Markup-Syntax für Kursivschrift . Downvotes sind hier allerdings etwas hart, da stimme ich zu.Da ich jetzt auch mit diesem Problem konfrontiert bin und keine Antwort auf eine andere, aber auch gültige Frage hinzufügen kann, die hier gestellt wird , werde ich eine Beispiellösung für das Problem bereitstellen: nur die Zeilennummer abrufen, in der die Funktion aufgerufen wurde C ++ mit Vorlagen.
Hintergrund: In C ++ können nicht ganzzahlige Ganzzahlwerte als Vorlagenargument verwendet werden. Dies unterscheidet sich von der typischen Verwendung von Datentypen als Vorlagenargumente. Die Idee ist also, solche ganzzahligen Werte für einen Funktionsaufruf zu verwenden.
Ausgabe:
Hier ist zu erwähnen, dass es in C ++ 11 Standard möglich ist, Standardvorlagenwerte für Funktionen mithilfe von Vorlagen anzugeben. In Pre C ++ 11 scheinen Standardwerte für Argumente ohne Typ nur für Klassenvorlagenargumente zu funktionieren. Daher wäre es in C ++ 11 nicht erforderlich, doppelte Funktionsdefinitionen wie oben zu haben. In C ++ 11 ist es auch gültig, const char * -Vorlagenargumente zu haben, aber es ist nicht möglich, sie mit Literalen wie
__FILE__
oder__func__
wie hier erwähnt zu verwenden .Wenn Sie also C ++ oder C ++ 11 verwenden, ist dies möglicherweise eine sehr interessante Alternative als die Verwendung von Makros, um die aufrufende Leitung zu erhalten.
quelle
Verwenden Sie
__LINE__
, aber was ist sein Typ?Als Ganzzahlkonstante kann Code häufig annehmen, dass der Wert
__LINE__ <= INT_MAX
und damit der Typ istint
.Zum Drucken in C wird
printf()
der passende Bezeichner benötigt :"%d"
. Dies ist in C ++ ein weitaus geringeres Problemcout
.Pedantisches Problem: Wenn die Zeilennummer
INT_MAX
1 überschreitet (mit 16 Bit etwas denkbarint
), wird der Compiler hoffentlich eine Warnung ausgeben. Beispiel:Alternativ könnte Code breitere Typen dazu zwingen, solchen Warnungen zuvorzukommen.
Vermeiden
printf()
So vermeiden Sie alle Einschränkungen für Ganzzahlen: stringify . Code kann direkt ohne
printf()
Anruf gedruckt werden : eine nette Sache, die Sie bei der Fehlerbehandlung vermeiden sollten 2 .1 Sicherlich schlechte Programmierpraxis, um eine so große Datei zu haben, aber vielleicht kann maschinengenerierter Code hoch gehen.
2 Beim Debuggen funktioniert Code manchmal einfach nicht wie erhofft. Das Aufrufen komplexer Funktionen wie
*printf()
kann selbst Probleme verursachen, im Gegensatz zu einfachenfputs()
.quelle
Für diejenigen, die es möglicherweise benötigen, ein "FILE_LINE" -Makro zum einfachen Drucken von Dateien und Zeilen:
quelle