Assert

Assert
Redundanz Die Artikel Assertion (Informatik) und Zusicherung (Softwaretechnik) überschneiden sich thematisch. Hilf mit, die Artikel besser voneinander abzugrenzen oder zu vereinigen. Beteilige dich dazu an der Diskussion über diese Überschneidungen. Bitte entferne diesen Baustein erst nach vollständiger Abarbeitung der Redundanz. Hafenbar 15:57, 24. Jun. 2008 (CEST)

Eine Zusicherung oder Assertion (lat./engl. für Aussage; Behauptung) ist eine Aussage über den Zustand eines Computer-Programms oder einer elektronischen Schaltung. Mit Hilfe von Zusicherungen können logische Fehler im Programm oder Defekte in der umgebenden Hard- oder Software erkannt und das Programm kontrolliert beendet werden. Bei der Entwicklung elektronischer Schaltungen kann mittels Assertions die Einhaltung der Spezifikation in der Verifikationsphase überprüft werden. Des Weiteren können Assertions Informationen über den Grad der Testabdeckung während der Verifikation liefern.

Inhaltsverzeichnis

Anwendung

Durch die Formulierung einer Zusicherung bringt der Entwickler eines Programms seine Überzeugung über bestimmte Bedingungen während der Laufzeit eines Programms zum Ausdruck und lässt sie Teil des Programms werden. Er trennt diese Überzeugungen von den normalen Laufzeitumständen ab und nimmt diese Bedingungen als stets wahr an. Abweichungen hiervon werden nicht regulär behandelt, damit die Vielzahl möglicher Fälle nicht die Lösung des Problems vereitelt, denn natürlich kann es während der Laufzeit eines Programms dazu kommen, dass 2+2=4 einmal nicht gilt, z. B. weil Variablen durch Programmfehler im Betriebssystem überschrieben wurden.

Damit unterscheiden sich Zusicherungen von der klassischen Fehlerkontrolle durch Kontrollstrukturen oder Ausnahmen (Exceptions), die einen Fehlerfall als mögliches Ergebnis einschließen. In einigen Programmiersprachen wurden Zusicherungen auf Sprachebene eingebaut, häufig werden sie als Sonderform der Ausnahmen verwirklicht.

Geschichte

Eingeführt wurde der Begriff Assertion von Robert Floyd 1967 in seinem Artikel Assigning Meanings to Programs. Er schlug eine Methode vor, mit der man die Korrektheit von Flussdiagrammen beweisen konnte indem man jedes Element des Flussdiagramms mit einer Zusicherung versieht. Floyd gab Regeln an, nach denen die Zusicherungen bestimmt werden konnten. Tony Hoare entwickelte diese Methode zum Hoare-Kalkül für prozedurale Programmiersprachen weiter. Im Hoare-Kalkül wird eine Zusicherung, die vor einer Anweisung steht, Vorbedingung (engl. precondition), eine Zusicherung nach einer Anweisung Nachbedingung (engl. postcondition) genannt. Eine Zusicherung, die bei jedem Schleifendurchlauf erfüllt sein muss, heißt Invariante.

Niklaus Wirth benutzte Zusicherungen zur Definition der Semantik von Pascal und schlug vor, dass Programmierer in ihre Programme Kommentare mit Zusicherungen schreiben sollten. Aus diesem Grund sind Kommentare in Pascal mit geschweiften Klammern {...} umgeben, eine Syntax, die Hoare in seinem Kalkül für Zusicherungen verwendet hatte.

In Borland Delphi wurde die Idee übernommen und ist als System-Funktion assert eingebaut. In der Programmiersprache Java steht seit Version 1.4 das Schlüsselwort assert zur Verfügung.

Die zur Entwicklung elektronischer Schaltungen eingesetzten Hardwarebeschreibungssprachen VHDL und SystemVerilog unterstützen Assertions. PSL ist eine eigenständige Beschreibungssprache für Assertions, die Modelle in VHDL, Verilog und SystemC unterstützt. Während der Verifikation wird vom Simulationswerkzeug erfasst, wie oft die Assertion ausgelöst wurde und wie oft die Zusicherung erfüllt oder verletzt wurde. Wurde die Assertion ausgelöst und die Zusicherung nie verletzt, gilt die Schaltung als erfolgreich verifiziert. Wurde jedoch die Assertion während der Simulation nie ausgelöst, besteht eine mangelnde Testabdeckung und die Verifikationsumgebung muss erweitert werden.

Programmierpraxis

In der Programmiersprache C könnte eine Zusicherung in etwa so eingesetzt werden:

#include <assert.h>
/// diese Funktion liefert die Länge eines nullterminierten Strings
/// falls der übergebene auf die Adresse NULL verweist, wird das
/// Programm kontrolliert abgebrochen. (strlen prüft das nicht selbst)
int strlenChecked(char* s) {
  assert(s != NULL);
  return strlen(s);
}

In diesem Beispiel wird über die Einbindung der Header-Datei assert.h das Makro assert verwendbar. Dieses Makro sorgt im Falle eines Fehlschlags für die Ausgabe einer Standardmeldung, in der die nicht erfüllte Bedingung zitiert wird und Dateiname und Zeilennummer hinzugefügt werden. Eine solche Meldung sieht dann so aus:

Assertation "s!=NULL" failed in file "C:\Projects\Sudoku\utils.c", line 9

Java kennt das Konzept der Zusicherungen ab Version 1.4. Hier wird allerdings das Programm nicht notwendigerweise beendet, sondern eine so genannte Ausnahme (englisch exception) geworfen, die innerhalb des Programms weiter verarbeitet werden kann.

Ein einfaches Beispiel einer Assertion (hier in Java-Syntax) ist

int n = readInput();
n = n * n; //Quadrieren
assert n >= 0;

Mit dieser Assertion sagt der Programmierer "Ich bin mir sicher, dass nach dieser Stelle n größer gleich null ist".

Bertrand Meyer hat die Idee von Zusicherungen in dem Programmierparadigma Design by Contract verarbeitet und in der Programmiersprache Eiffel umgesetzt. Vorbedingungen werden durch require-Klauseln, Nachbedingungen durch ensure-Klauseln beschrieben. Für Klassen können Invarianten spezifiziert werden. Auch in Eiffel werden Ausnahmen geworfen, wenn eine Zusicherung nicht erfüllt ist.

Verwandte Techniken

Assertations entdecken Programmfehler zur Laufzeit, beim Anwender, also erst wenn es zu spät ist. Um Meldungen über "Interne Fehler" möglichst zu vermeiden, versucht man durch geeignete Formulierung des Quelltextes logische Fehler bereits zur Kompilierzeit (durch den Compiler) in Form von Fehlern und Warnungen aufdecken zu lassen. Logische Fehler, die man auf diese Weise nicht finden kann, können häufig mittels Modultests aufgedeckt werden.

Umformulieren des Quelltextes

Indem Fallunterscheidungen auf ein Minimum reduziert werden, ist mancher Fehler nicht ausdrückbar, dann ist er als logischer Fehler auch nicht möglich. Nehmen wir an es gäbe nur zwei mögliche Fälle (das ist in der Tat häufig so) dann könnten wir einen einfachen Wahrheitswert verwenden anstelle einer spezielleren Kodierung:

/// Funktion liefert den Text zu einem Geschlechtskode
const char* genderStr(bool isFemale) {
  return isFemale ? "weiblich" : "männlich";
}

auch wenn es politisch korrekter wäre, enthält das folgende Beispiel eine (scheinbar) absurde Fehlermöglichkeit:

/// Geschlechtskennung als Enumeration:
enum GENDER { GENDER_MALE, GENDER_FEMALE };
/// Funktion liefert den Text zu einem Geschlechtskode
const char* genderStr(GENDER gender) {
  switch(gender) {
    case GENDER_FEMALE: return "weiblich";
    case GENDER_MALE:   return "männlich";
    default:            assert(0); return ""; // ???
  }
}

Zusicherungen zur Kompilierzeit

Während die oben beschriebenen Assertionen zur Laufzeit des Programms geprüft werden, gibt es in C++ die Möglichkeit, Bedingungen auch schon beim Übersetzen des Programms durch den Compiler zu überprüfen. Es können nur Bedingungen nachgeprüft werden, die zur Übersetzungszeit bekannt sind, z. B. sizeof(int) == 4. Schlägt ein Test fehl, lässt sich das Programm nicht übersetzen:

#if sizeof(int) != 4
  #error "unerwartete int-Größe"
#endif

Allerdings hängt das stark von der Funktionalität des jeweiligen Compilers ab und manche Formulierungen sind gewöhnungsbedürftig:

/// Die Korrektheit unserer Implementierung hängt davon ab, 
/// dass ein int 4 Bytes groß ist. Falls dies nicht gilt, 
/// bricht der Compiler mit der Meldung ab, dass 
/// Arrays mindestens ein Element haben müssen:
void validIntSize(void) {
  int valid[sizeof(int)==4];
}

Zusicherungen in Modultests

Ein Bereich in dem ebenfalls Zusicherungen eine Rolle spielen, sind Modultests (u. A. Kernbestandteil des Extreme Programmings). Wann immer man am Quelltext Änderungen (z. B. Refactorings) vornimmt, z. B. um weitere Funktionen zu integrieren, führt man Tests auf Teilfunktionen (Modulen, also z. B. Funktionen Prozeduren, Klassen) aus, um die bekannte (gewünschte) Funktionalität zu evaluieren.

Im Gegensatz zu assert wird bei einem Fehlschlag nicht das ganze Programm beendet, sondern nur der Test als gescheitert betrachtet und weitere Tests ausgeführt, um möglichst viele Fehler zu finden. Laufen alle Tests fehlerfrei, dann sollte davon ausgegangen werden können, dass die gewünschte Funktionalität besteht.

Von besonderer Bedeutung ist der Umstand, dass Modultests üblicherweise nicht im Produktivcode ausgeführt werden, sondern zur Entwicklungszeit. Das bedeutet, dass Assertions im fertigen Programm als Gegenpart zu betrachten sind.

Spezielle Techniken für Microsoft-Compiler

Neben Assert wird häufig auch Verify verwendet. Verify führt alle Anweisungen aus, die in die Berechnung der Bedingung einfließen, gleichgültig, ob mit oder ohne Debug-Absicht kompiliert wurde. Die Überprüfung findet aber nur in der Debug-Variante statt, d.h. auch hier kann ein Programm in obskurer Weise scheitern, falls die Zusicherung nicht erfüllt ist.

// die Variable anzahl wird immer erhöht
Verify(++anzahl>2);

Assert_Valid wird eingesetzt, um Objekte auf ihre Gültigkeit zu testen. Dazu gibt es in der Basisklasse der Objekthierarchie die virtuelle Methode AssertValid(). Die Methode sollte für jede konkrete Klasse überschrieben werden, um die internen Felder der Klasse auf Gültigkeit zu testen.

// Example for CObject::AssertValid.
void CAge::AssertValid() const
{
  CObject::AssertValid();
  ASSERT( m_years > 0 );
  ASSERT( m_years < 105 );
}

Weblinks

Literatur

  • Robert W. Floyd: Assigning meanings to programs, Proceedings of Symposia in Applied Mathematics, Volume 19 (1967), Seite 19–32.

Wikimedia Foundation.

Игры ⚽ Поможем написать курсовую

Schlagen Sie auch in anderen Wörterbüchern nach:

  • Assert.h — Стандартная библиотека языка программирования С assert.h complex.h ctype.h errno.h fenv.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h stdint.h stdio.h …   Википедия

  • Assert — As*sert , v. t. [imp. & p. p. {Asserted}; p. pr. & vb. n. {Asserting}.] [L. assertus, p. p. of asserere to join or fasten to one s self, claim, maintain; ad + serere to join or bind together. See {Series}.] 1. To affirm; to declare with assurance …   The Collaborative International Dictionary of English

  • Assert.h — is a header file in the standard library of the C programming language that defines the C preprocessor macro assert(). The macro implements an assertion, which can be used to verify assumptions made by the program.The assert() macro inserts… …   Wikipedia

  • Assert.h — Saltar a navegación, búsqueda assert.h es un archivo de cabecera de la biblioteca estándar del Lenguaje de programación C, en el que se define la macro de depuración assert (aserción, en inglés), que implemeta una aserción (test), usada para… …   Wikipedia Español

  • assert — 1 Assert, declare, profess, affirm, aver, protest, avouch, avow, predicate, warrant agree in meaning to state positively usually either in anticipation of denial or objection or in the face of it. Assert implies absence of proof: it usually… …   New Dictionary of Synonyms

  • assert.h — <assert.h> est un en tête présent dans la bibliothèque standard du langage C qui définit la macro assert. La macro met en œuvre une assertion, qui peut être utilisée pour vérifier les hypothèses formulées par le programme. La macro assert… …   Wikipédia en Français

  • assert — [ə sʉrt′] vt. [< L assertus, pp. of asserere, to join to, claim < ad , to + serere, join: see SERIES] 1. to state positively; declare; affirm 2. to maintain or defend (rights, claims, etc.) assert oneself to insist on one s rights, or on… …   English World dictionary

  • assert — as·sert /ə sərt/ vt: to present and demand recognition of assert a claim as·ser·tion /ə sər shən/ n Merriam Webster’s Dictionary of Law. Merriam Webster. 1996 …   Law dictionary

  • assert — c.1600, declare, from L. assertus, pp. of asserere claim, maintain, affirm (see ASSERTION (Cf. assertion)). Related: Asserted; asserting. To assert oneself stand up for one s rights is recorded from 1879 …   Etymology dictionary

  • assert — ► VERB 1) state (a fact or belief) confidently and forcefully. 2) cause others to recognize (something) by confident and forceful behaviour. 3) (assert oneself) be confident and forceful. ORIGIN Latin asserere claim, affirm …   English terms dictionary

  • assert — [v] insist, declare, maintain advance, affirm, allege, argue, asservate, attest, aver, avouch, avow, butt in*, cite, claim, contend, defend, horn in, justify, mouth off*, pop off*, predicate, press, proclaim, profess, pronounce, protest, put… …   New thesaurus

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”