wake-up-neo.com

C / C ++ Zeilennummer

Kann ich aus Gründen der Fehlersuche die Zeilennummer in C /C++ - Compilern erhalten? (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)
98
Betamoo

Sie sollten das Präprozessor-Makro __LINE__ Und __FILE__ Verwenden. 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 für die aktuelle Zeilennummer und den aktuellen Dateinamen enthält.

Andere Präprozessorvariablen:

  • __func__: Funktionsname (dies ist Teil von C99 , nicht alle C++ - Compiler unterstützen ihn)
  • __DATE__: Eine Zeichenfolge der Form "MMM TT JJJJ"
  • __TIME__: Eine Zeichenfolge der Form "hh: mm: ss"

Ihr Code wird sein:

if(!Logical)
  printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
162
Julien Hoarau

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.

__LINE__: Die Zeilennummer der aktuellen Quellzeile (eine Dezimalkonstante).
__FILE__: Der vermutete Name der Quelldatei (ein Zeichenkettenliteral).
__DATE__: Das Datum der Übersetzung der Quelldatei (ein Zeichenkettenliteral ...)
__TIME__: Der Zeitpunkt der Übersetzung der Quelldatei (ein Zeichenkettenliteral ...)
__STDC__: Ob__STDC__ ist vordefiniert
__cplusplus: Der Name __cplusplus wird beim Kompilieren einer C++ - Übersetzungseinheit auf den Wert 199711L definiert

Ihr Code wäre also:

if(!Logical)
  printf("Not logical value at line number %d \n",__LINE__);
61
Brian R. Bondy

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:

#include <cstdio>  //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a,  __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)

Diese Makros sollten sich identisch zu printf () verhalten und gleichzeitig Java stacktrace-ähnliche Informationen enthalten. Hier ein Beispiel für main:

void exampleMethod() {
    println("printf() syntax: string = %s, int = %d", "foobar", 42);
}

int main(int argc, char** argv) {
    print("Before exampleMethod()...\n");
    exampleMethod();
    println("Success!");
}

Was zu folgender Ausgabe führt:

main (main.cpp: 11) Vor exampleMethod () ...
exampleMethod (main.cpp: 7) printf () -Syntax: string = foobar, int = 42
main (main.cpp: 13) Erfolg!

18

Verwenden __LINE__ (doppelter Unterstrich LINE doppelter Unterstrich), der Präprozessor ersetzt ihn durch die Zeilennummer, in der er vorkommt.

11
meagar

Auschecken __FILE__ und __LINE__ Makros

9
Anton

Versuchen __FILE__ und __LINE__.
Möglicherweise finden Sie auch __DATE__ und __TIME__ sinnvoll.
Sie sollten das normale Debuggen verwenden, es sei denn, Sie müssen ein Programm auf der Clientseite debuggen und müssen diese Informationen protokollieren.

4
Sanctus2099

Da ich jetzt auch mit diesem Problem konfrontiert bin und ich keine Antwort auf eine andere, aber auch gültige Frage hinzufügen kann hier , werde ich eine beispielhafte Lösung für das Problem liefern: nur die Zeilennummer von Dabei wurde die Funktion in C++ mithilfe von Vorlagen aufgerufen.

Hintergrund: In C++ kann man nicht-typisierte Integer-Werte als Template-Argument verwenden. Dies unterscheidet sich von der typischen Verwendung von Datentypen als Vorlagenargumente. Die Idee ist also, solche ganzzahligen Werte für einen Funktionsaufruf zu verwenden.

#include <iostream>

class Test{
    public:
        template<unsigned int L>
        int test(){
            std::cout << "the function has been called at line number: " << L << std::endl;
            return 0;
        }
        int test(){ return this->test<0>(); }
};

int main(int argc, char **argv){
    Test t;
    t.test();
    t.test<__LINE__>();
    return 0;
}

Ausgabe:

die Funktion wurde auf der Zeilennummer 0 aufgerufen

die Funktion wurde unter folgender Zeilennummer aufgerufen: 16

Eine Sache, die hier erwähnt werden muss, ist, dass es in C++ 11 Standard möglich ist, Standardvorlagenwerte für Funktionen mithilfe von Vorlagen anzugeben. In Vorgängerversionen von C++ 11 scheinen Standardwerte für Argumente ohne Typ nur für Klassenvorlagenargumente zu funktionieren. In C++ 11 wären daher keine doppelten Funktionsdefinitionen wie oben erforderlich. In C++ 11 ist es auch gültig, Argumente für const char * -Vorlagen zu haben, aber es ist nicht möglich, sie mit Literalen wie __FILE__ Oder __func__ Wie erwähnt zu verwenden hier .

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.

1
John Doe