Static Assertion

Beim Programmieren das Verhältnis zweier Konstanten gewissen Bedingungen unterstellen, ohne sie direkt auf einander beziehen zu müssen? Static Assertions bieten eine Möglichkeit, das zu tun – mit einer Meldung zur Kompilierzeit.

Was ist  eine Static Assertion?

Eine Assertion (deutsch "Zusicherung") dient dazu, im Sourcecode eine Bedingung sicherzustellen. Im Gegensatz zu einer "normalen" Assertion bzw. Laufzeit-Assertion, wo die Bedingung zur Laufzeit geprüft wird, erfolgt die Prüfung einer Static Assertion zur Kompilierzeit, also beim Übersetzen des Sourcecodes. Eine nicht erfüllte Bedingung wird somit bereits vom Compiler beim Übersetzen bemerkt und mit einer Compiler-Fehlermeldung gemeldet.

Eigenschaften der Static Assertion

Für Bedingungen, welche bereits zur Kompilierzeit geprüft werden können, ist die Static Assertion der Laufzeit-Assertion vorzuziehen. Eine Static Assertion bietet folgende Vorteile:

  • Kein belegter Speicherplatz
  • Keine Performance-Einbusse zur Laufzeit
  • Kein Durchlauf eines bestimmten Programm-Pfades nötig

Eine korrekt implementierte Static Assertion belegt keinen Speicherplatz, wenn die beim Kompilieren geprüfte Bedingung erfüllt ist.

Für eine korrekt implementierte Static Assertion wird kein Maschinencode erzeugt, wenn die beim Kompilieren geprüfte Bedingung erfüllt ist. Zur Laufzeit wird deshalb kein Code durchlaufen und die Performance nicht gestört.

Eine Laufzeit-Assertion wird im Sourcecode an einer bestimmten Stelle platziert. Damit es geprüft wird, muss dieser Pfad durchlaufen werden. Wenn die Assert-Anweisung unglücklich platziert wird oder beim Test nicht die Funktionen ausgeführt werden, bei welchen der Pfad durchlaufen wird, wird sie nicht geprüft. Die nicht erfüllte Bedingung wird nicht oder zu spät entdeckt. Im Gegensatz dazu wird eine Static Assertion bereits beim Kompilieren des Sourcecodes geprüft. Das Durchlaufen eines bestimmten Pfades zur Laufzeit ist zur Prüfung nicht notwendig. Somit ist eine Fehlerquelle eliminiert.

Einsatzgebiete

Eine Static Assertion kann eingesetzt werden, wenn die überprüfte Bedingung vom Compiler ausgewertet werden kann. Es bieten sich zum Beispiel folgende Einsatzmöglichkeiten an:

  • Sicherstellen von korrekten bzw. Mindest-Speichergrössen von Datentypen
  • Sicherstellen von korrekten Verhältnissen von Konstanten zueinander

Beispiel

Im folgenden Beispiel werden Werte in einer Tabelle abgespeichert. Die Anzahl der zur Verfügung stehenden Tabellenplätze ist 32. An anderer Stelle im Programm werden die Einträge der Tabelle in einen Buffer eingefüllt, welcher auf die Grösse von 128 Bytes festgelegt ist - zum Beispiel zur Übertragung. Ein direktes voneinander abhängig machen der beiden Konstanten ist hier nicht erwünscht, weil beide Grössen in ihrem eignen Kontext definiert werden. Allerdings soll vermieden werden, dass die Tabelle den zur Verfügung stehenden Speicherplatz überschreitet. Dies kann mit einer Static Assertion erreicht werden:

const int iTabItemCountC = 32;
...
const int iMsgBufferLenC = 128;
...
static_assert(iTabItemCountC * sizeof(TabItem) <= iMsgBufferLenC, "Tabelle groesser als Buffer");

Mit dem Befehl static_assert wird geprüft, ob die Tabelle von Werten im Buffer Platz hat. Wenn die Speichergrösse der Tabelle die Buffergrösse überschreitet, wird beim Kompilieren die Meldung Tabelle groesser als Buffer angezeigt.

Verfügbarkeit von Static Assertions in C/C++

In C++ ist die Static Assertion mit C++11 eingeführt worden. Für Compiler, welche diesen Standard nicht unterstützen empfiehlt sich die entsprechende Boost-Library.

In C ist die Static Assertion mit C11 eingeführt worden. Für Compiler, welche diesen Standard nicht unterstützen, muss auf eine eigene Implementation zurückgegriffen werden (beschrieben in der englischen Wikipedia, Link unten).
Der Nachteil einer eigenen Implementation ist die nicht leicht verständliche Compiler-Fehlermeldung. Weil Effekte ausgenützt werden, welche mit einer Assertion nichts zu tun haben, bezieht sich auch die vom Compiler generierte Fehlermeldung nicht auf die Assertion.

Weiterführende Information

Allgemeine Information:

Deutsche Wikipedia zum Thema "Zusicherungen zur Kompilierzeit"

Englische Wikipedia zum Thema "Static Assertions"

C++:

cppreference.com zu static_assert

Boost-Library Funktion BOOST_STATIC_ASSERT

Microsoft zu static_assert in Visual Studio

C:

Blog robertgamble.net zu static assertions in C11

Microsoft zu _STATIC_ASSERT Macro