Vordefinierte Makros

Der Preprozessor liefert standardmässig einige vordefinierte Makros, die in jedem Code zur Verfügung stehen. Je nach System kann jedoch der Umfang der vordefinierten Makros variieren. Hier werden nur die allerwichtigsten aufgeführt.

Standard-Makros

Die Folgenden Makros sollten auf jedem System unter jedem Compiler verfügbar sein.

__FILE__   Returns the full path of the file as a string.
           Can be controlled using the #linedirective .
__LINE__   Returns the current line number as a constant.
           Can be controlled using the #linedirective .
__DATE__   Returns the current date as a string.
__TIME__   Returns the current time as a string.



File: test.cpp
Line: 5
Date: Aug 27 2007
Time: 21:23:48
#include <stdio.h>

int main(){
  printf("File: %s\n", __FILE__);
  printf("Line: %d\n", __LINE__);
  printf("Date: %s\n", __DATE__);
  printf("Time: %s\n", __TIME__);
  return 0;
}

Debug oder Release

Ein weiteres Makro, welches auf den meisten Systemen in der einen oder anderen Form gebraucht wird, ist die Information, ob der Compiler eine Debug-Version compiliert, oder eine Release-Version. Das einzige Makro, welches gemäss Standard für diesen Fall existiert, ist NDEBUG, was soviel bedeutet wie NON-Debug. Diese Konstante sollte dann definiert sein, wenn der Compiler eine Release-Version erstellt.

Häufig werden bei Debug-Compilaten zusätzliche Überprüfungen einprogrammiert, welche jedoch in der Release-Version nicht ausgeführt werden sollen. Hier ein Beispiel für eine solche Prüfung:

double getInverse(double x){
  #ifndef NDEBUG
    if(x == 0.f){
      printf("Warning! Inverse of zero.\n");
      return 0.f;
    }
  #endif
  return 1.f / x;
}

Es ist zu beachten, dass die Schreibweise mit dem ifndef als doppelte Verneinung zu verstehen ist: Falls der Compiler NICHT in dem NICHT-Debug-Modus ist, dann führe Debug-Code aus. Dies ist zu Beginn möglicherweise verwirrend, wird jedoch so verwendet.

Einige Funktionen der Standardbibliotheken prüfen dieses Makro und führen je nach Fall erweiterte Überprüfungen durch. Beispielsweise wird die assert()-Funktion als leere Funktion definiert, wenn NDEBUG definiert ist. Nicht alle Systeme definieren diese Konstante jedoch automatisch, sie muss dementsprechend möglicherweise bei den Compilier-Einstellungen für Release-Versionen manuell gesetzt werden.

C oder C++ Compiler

Heutige Entwicklungsumgebungen erkennen anhand der Dateiendung, ob ein C oder ein C++ Compiler aufgerufen werden soll. Innerhalb einer Header-Datei kann diese Entscheidung mithilfe von Makros geprüft werden. Mittlerweile haben sich die meisten Compiler darauf geeinigt, dieselben Makros zu verwenden. In der folgenden Tabelle sind der Vollständigkeit halber auch noch zwei andere, häufig gefragte Makros angegeben.

__ASSEMBLER__ Should be defined, when an Assembler is running.
__STDC__      Should be defined, when the C compiler is standardized.
__cplusplus   Should be defined, when the C++ is being compiled.
__OBJC__      Should be defined, when the Objective-C is being compiled.

Variable Parameter

Wenn mittels der #define-Direktive ein Makro mit variabler Anzahl Argumente definiert wird, stellt der Preprozessor diese als ein Makro __VA_ARGS__, zur Verfügung.

#define PRINT(string, ...) printf(string, __VA_ARGS__)