Programmierung zur Compilezeit

Autor / Redakteur: Rainer Grimm* / Christine Kremser

Was haben klassische Template-Metaprogrammierung, die Funktionen der Type-Traits Bibliothek und konstante Ausdrücke gemein? Sie werden alle zur Compilezeit ausgeführt. Damit vereinen sie höhere Performanz mit erweiterter Funktionalität. Höhere Performanz, da Berechnungen zur Lauf- auf die Compilezeit verlegt werden. Doch wie funktioniert die ganze Magie?

Anbieter zum Thema

(Bild: gemeinfrei/Pixabay / CC0 )

Template Metaprogrammierung

1994 entdeckte Erwin Unruh Template Metaprogrammierung durch einen Zufall. Sein Programm berechnete die ersten 30 Primzahlen zur Compilezeit. Die Ausgabe der Primzahlen war Teil der Fehlermeldung in Bild 2 (vgl. Bildergalerie).

Bildergalerie
Bildergalerie mit 12 Bildern

Wie funktioniert die ganze Magie? Der Compiler instanziiert die Templates und erzeugt den temporären C++-Sourcecode, der zusammen mit dem restlichen Sourcecode übersetzt wird. Zur Laufzeit des Programmes steht damit nur der ausführbare Code zur Verfügung.

So führt der Aufruf der Fakultät Funktion Factorial<5>::value in dem kleinen Codebeispiel in Bild 3 (vgl. Bildergalerie) dazu, dass der Wert zur Compilezeit berechnet wird.

Schön zeigt Bild 4 (vgl. Bildergalerie), dass der Wert der Faktultät von 5 bereits zur Laufzeit als Konstante vorliegt. Dabei instanziiert der Compiler den Ausdruck Factorial<5>::value. Um diesen Wert zu berechnen, benötigt er den Ausdruck Factorial<4>::value. Diese Rekursion endet dann, wenn der Wert Factorial<1>::value benötigt wird, denn deren Wert ist 1.

Funktionen wie die Factorial Funktion, die zur Compilezeit ausgeführt werden, werden Metafunktionen genannt. Sie besitzen ein paar interessante Eigenschaften. Neben Ganzzahlen können sie auch Typen und Klassen-Typen als Template-Parameter verwenden. Metafunktionen sind unter der Decke Klassen-Templates. Sie können ihre Daten nicht modifizieren, sondern erzeugen auf Bedarf neue Daten.

Template Metaprogrammierung, die auf Metafunktionen basiert, die zur Compilezeit auf ihren Metadaten agieren, ist eine rein funktionale Subsprache in der imperativen Sprache C++. Diese funktionale Subsprache ist Turing-vollständig [1], und entspricht in ihrer Mächtigkeit der der Programmiersprachen C++, C oder Java.

Template Metaprogrammierung ist die Grundlage für viele Boost-Bibliotheken [2]. Das trifft auch auf die Type-Traits Bibliothek zu, die seit C++11 Teil des C++-Standards ist.

(ID:44192399)