2012-03-27 22 views
0

Ich habe etwas älteren C++ - Code, den ich versuche, ein bisschen besser zu verstehen. Ein Problem, ich bin immer verwirrt mit ist dies mit einer Zeile wie folgt:Legacy-C++ verstehen #define

#define LOG_TRACE_ERROR(s) LOG_traceError(_T(__FILE__), __LINE__, s) 

, die in einer Header-Datei ist. Ich kann sehen, LOG_TRACE_ERROR ist, was der Code aufruft und es übergibt es eine Zeichenfolge, und ich kann sehen, dass LOG_traceError ist eine Funktion, die tatsächlich die Arbeit tut, so nehme ich an, diese Zeile ist die beiden verschiedenen Namen für die Zuordnung zusammen funktionieren? Was mich verwirrt ist, warum ist die Parameterliste anders (nur eine Zeichenkette für LOG_TRACE_ERROR und (_T (FILE), LINE, s) für LOG_traceError). Ich kann auch finden _ FILE _ oder _ LINE _ oder s definiert überall so wie weiß das Programm, was sie sind?

Antwort

5

_FILE_ wird auf den Dateinamen erweitert.

_LINE_ wird auf die Zeilennummer erweitert.

s ist der Parameter, den Sie an das Makro übergeben.

Wenn Sie schreiben:

//file.cpp 
//... 
LOG_TRACE_ERROR("error here"); //line 13 

der Präprozessor verwandeln wird es an:

//file.cpp 
//... 
LOG_traceError(_T("file.cpp"), "13", "error here"); 

_T() ist ein Makro zu UNICODE verwandt. In einer Unicode-Umgebung wird die Zeichenfolge in eine wchar_t* umgewandelt.

3

__FILE__ und __LINE__ sind interne Werte, die von Ihrem Compiler definiert werden und sich auf die kompilierte Datei und die aktuelle Zeile (das Makro wird um expandiert) erweitern.

Mit Hilfe von Makros, wenn Sie (zum Beispiel) sagen:

#define YOUR_MACRO(param1, param2) some_function_here(param1 + param2, 0) 

Sie ein Makro mit zwei Parametern definieren param1 und param2 (in Ihrem Fall gibt es nur einen Parameter und sein Name ist s). Sie können diese Parameter dann in Ihrer Makrodefinition verwenden, wie Sie es für richtig halten.

Hinweis: Sie sollten vorsichtig sein beim Schreiben von Makros, da sie schwierig werden können. In dem obigen Beispiel, wenn Sie aufrufen:

YOUR_MACRO(x << 2, y << 2) 

wäre es erweitern:

some_function_here(x << 2 + y << 2, 0); 

das ist eigentlich:

some_function_here(x << (2 + y) << 2, 0); 

sicherlich nicht das, was Sie gemeint! Das Schreiben von guten Makros beinhaltet eine Menge Klammern und vielleicht die Verwendung von Nicht-Standard-Features Ihres Compilers, um sie sicher zu machen.

0

_FILE_ und _LINE_ stammen von Ihrem Präprozessor. Ein Makro wie dieses ist die einzige Möglichkeit, auf diese Werte für die Zeile zuzugreifen, in der Sie Log_traceError (...) aufrufen, wenn der Benutzer bei jedem Aufruf von LOG_traceError (...) nicht _FILE_ und _LINE_ eingeben soll.

2

__FILE__ und __LINE__, zusammen mit __DATE__, __TIME__ und ein paar anderen, sind vordefinierte Makros zunächst in der ISO/IEC 9899: 1990 (C89) Standard für die Programmiersprache C, Abschnitt §6.10.8 :

6.10.8 vordefinierten Makronamen

die folgenden Makronamen werden von der Implementierung de fi niert sein:

__DATE__ Das Datum der Übersetzung der vorverarbeitenden Übersetzungseinheit: ein Zeichen String-Literal der Form "Mmm dd yyyy", wobei die Namen der Monate die von der asctime -Funktion generierten und das erste Zeichen sind von dd ist ein Leerzeichen, wenn der Wert kleiner als 10 ist. Wenn das Datum der Übersetzung nicht verfügbar ist, muss ein umsetzungsdefiniertes Gültigkeitsdatum angegeben werden.

__FILE__ Der vermutete Name der aktuellen Quelldatei (ein Zeichenkettenliteral).

__LINE__ Die angenommene Zeilennummer (in der aktuellen Quelldatei) der aktuellen Quellzeile (eine Ganzzahlkonstante).

__STDC__ Die Ganzzahlkonstante 1, die eine konforme Implementierung anzeigen soll.

__STDC_HOSTED__ Die Ganzzahlkonstante 1, wenn die Implementierung eine gehostete Implementierung ist, oder die Ganzzahlkonstante 0, wenn dies nicht der Fall ist.

__STDC_VERSION__ Die Ganzzahlkonstante 199901L.

__TIME__ Der Zeitpunkt der Übersetzung der vorverarbeitenden Übersetzungseinheit: ein Zeichenkettenliteral der Form "hh: mm: ss" wie in der Zeit , die von der asctime-Funktion generiert wird. Wenn der Zeitpunkt der Übersetzung nicht zur Verfügung steht, muss eine implementierungsdefinierte gültige Zeit angegeben werden.

Wie alle Makros werden sie vom Präprozessor ausgewertet, bevor der Code kompiliert wird.