<< WindowPtr
>> Fehlende Funktionen

Was sind Pragmas?

Pragmas sind spezielle Anweisungen an den C-Compiler. Zwei Probleme entstehen bei der Verwendung von Pragmas:
  1. Pragmas sind hochgradig compilerspezifisch. Nicht einmal die Amiga-Compiler haben dieselben Pragmas, selbst wenn damit das gleiche bewirkt wird.
  2. Man kann sich nicht darauf verlassen, daß ein Compiler Pragmas ignoriert, die er nicht versteht. Dies gilt selbst dann, wenn man einen Ausdruck wie den folgenden verwendet:
        #ifndef MY_COMPILER
        #pragma DoAnything
        #endif
    
Das letztere Problem läßt sich umgehen, indem man Pragmas wie folgt in eigene Include-Files setzt. (Das gleiche gilt übrigens auch für Präprozessor-Kommandos wie #asm (Aztec-C) oder #extern (C++).)
    #ifndef MY_COMPILER
    #include <mypragmas.h>
    #endif

Aber was machen Pragmas auf dem Amiga? Meistens werden sie verwendet, um dem Compiler mitzuteilen, wie gewisse Library-Funktionen aufgerufen werden. (Tatsächlich wird fast immer diese Verwendung gemeint, wenn Amiga-Besitzer über Pragmas sprechen.) Gewöhnliche C-Funktionen erwarten ihre Argumente auf dem Stack, Library-Funktionen dagegen in bestimmten Registern. Ferner erwarten sie den Library-Base-Pointer in Register a6. Betrachten wir eine Pragma-Anweisung von Aztec-C:

    #pragma amicall(SysBase,0xd2,FreeMem(a1,d0))
Dies weist den Compiler an, das erste Argument in Register a1 und das zweite in d0 zu laden. Ferner wird der Inhalt der Variablen SysBase in Register a6 geladen. Maxon-Pragmas sehen genauso aus, Dice- und SAS-Pragmas sind allerdings etwas komplizierter:
    #pragma libcall SysBase FreeMem d2 0902
Hier ist d2 (wie 0xd2 oben) der Library-Vektor-Offset (siehe nächstes Beispiel). Die letzte Ziffer ist die Zahl der Argumente, die davorstehende 0 ein Code für das Register mit dem Ergebnis und die davor stehenden Ziffern sind Codes für die Register mit den Argumenten in verkehrter Reihenfolge. (Die Codes bedeuten 0=d0, 1=d1, .., 8=a0, 9=a1, a=a2, ..)

Ein Kommando wie `FreeMem(fib,sizeof(*fib);' würde ein Compiler nun in folgenden Code übersetzen:

    move.l  _fib,a1
    move.l  260,d1	    ; sizeof(struct FileInfoBlock)
    move.l  _SysBase,a6
    jsr     -0xd2(a6)       ; 0xd2 = _LVOFreeMem
FreeMem in dieser Art aufzurufen ist kürzer und schneller als zunächst die Argumente auf den Stack zu legen und dann eine Funktion _FreeMem aufzurufen, die letzten Endes doch nur dasselbe tun und die Argumente vom Stack in dieselben Register laden würde.

Das Portierungsproblem der Pragmas umgeht man, indem man sie folgendermaßen in den eigenen Quelltext einbindet:

    /*  SAS/C, Dice und GNU-c (ab Version 2.6.1) machen es	*/
    /*  ganz einfach:						*/
    #if defined(__SASC)  ||  defined(_DCC)  ||  defined(__GNUC__)
      #include <proto/exec.h>
    #else

      /*  Lade den Funktionsprototyp. Dieser ist nicht vom	*/
      /*  verwendeten Compiler abhängig.			*/
      #include <clib/exec_protos.h>

      /*  Pragmas sind vom Compiler abhängig, aber wenigstens	*/
      /*  die Namen der Dateien mit Pragmas sind relativ	*/
      /*  einheitlich.						*/
      #ifdef AZTEC_C
        #include <pragmas/exec_lib.h>
      #elif defined(__MAXON__)
        #include <pragmas/exec_pragmas.h>
      #endif

      /*  Deklariere SysBase-Variable				*/
      extern struct ExecBase *SysBase;
    #endif
Das obige Beispiel kann problemlos mit allen angegebenen Compilern verwendet werden und produziert optimalen Code. (Die proto/*.h-Files machen übrigens auch nichts anderes als clib/*_protos.h und pragmas/*_pragmas.h mit #include einzulesen und dann die SysBase-Variable zu deklarieren.)

Eine abschließende Frage bleibt allerdings: Wie bekommt man die Pragmas? Die meisten Compiler haben bereits fertige Pragmas im Lieferumfang. Allerdings hilft das nicht, wenn man z.B. eine neue Library benutzen möchte oder nur die Pragmas einer veralteten Version hat. In diesem Fall kann man die Pragmas selbst aus den sogenannten FD-Files erzeugen. Dazu haben die meisten Compiler ein Utility namens fd2pragma. (Das NDU hat z.B. ein Directory namens FD, in dem die FD-Files aller Libraries und Devices des OS enthalten sind. siehe Abschnitt Wo bekomme ich die Amiga-Include-Dateien?) Es gibt auch ein frei kopierbares fd2pragma, das Pragmas für Aztec, Dice, SAS und Maxon sowie LVO-Files für den Aztec-Assembler und eventuelle Tag-Versionen produziert. (Aminet, `dev/misc/fd2pragma2_0.lha' oder auf den Fish-CDs)

Für Pragmas unter dem gcc siehe Abschnitt Inline-Dateien.



<< WindowPtr >> Fehlende Funktionen