Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++...

47
1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12 TU Dortmund [email protected] http://ess.cs.uni-dortmund.de/~os/ http://ess.cs.tu-dortmund.de/DE/Teaching/SS2010/SuS/

Transcript of Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++...

Page 1: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

11

Software ubiquitärer SystemeAnwendungsentwicklung in C/C++

Olaf SpinczykArbeitsgruppe Eingebettete Systemsoftware

Lehrstuhl für Informatik 12TU Dortmund [email protected]://ess.cs.uni-dortmund.de/~os/

http://ess.cs.tu-dortmund.de/DE/Teaching/SS2010/SuS/

Page 2: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 22

Inhalt● Motivation

● Sicheres Programmieren in C und C++● MISRA C● Embedded C++● Cyclone

● Ressourcenverbrauch von C++ gegenüber C● Laufzeit-Polymorphie● Parametrische Polymorphie

● Zusammenfassung

HardwareHardware

BetriebssystemBetriebssystem

MiddlewareMiddleware

DatenhaltungDatenhaltung

Anwendung/ProgrammierungAnwendung/Programmierung

Page 3: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 33

Inhalt● Motivation

● Sicheres Programmieren in C und C++● MISRA C● Embedded C++● Cyclone

● Ressourcenverbrauch von C++ gegenüber C● Laufzeit-Polymorphie● Parametrische Polymorphie

● Zusammenfassung

Page 4: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 44

Verbreitung von C und C++● Statistik über den Einsatz von Programmiersprachen bei

der Entwicklung eingebetteter Systeme● Daten beruhen auf einer Umfrage bei 74 Unternehmen der Branche

CC++

AssemblerJava.Net

SystemCIEC 61131

4GL SprachenDSL

sonstige

0 10 20 30 40 50 60 70

5858

5858

4343

4242

3232

1818

1818

1212

77

88

Einsatz in %

Quelle: Computer Zeitung Nr. 23, Juni 2009, S. 16

Page 5: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 55

Warum C und C++? (1)● Transparency and Control [1]● Beispiele

● Datenstrukturen wie Arrays von Structs werden einfach linear im Speicher abgelegt. Zugriffe sind durch Cache-Lokalität sehr schnell.- In Java bestimmen der Compiler und das Laufzeitsystem die

Objektplazierung (keine Transparenz).

● C Datentypen werden direkt auf die Hardwaredatentypen abgebildet- In Java wird von der realen Hardware abstrahiert.

● C Programme verwalten den Heap-Speicher manuell.Dies gibt dem Programmierer mehr Kontrolle über die Performance.- Java arbeitet mit einem Garbage Collector. Die Strategie bleibt dem

Laufzeitsystem überlassen.

● C/C++ Programme ...● lassen sich manuell optimieren. Man sieht ihnen die verursachten

Kosten direkt an.● sind in der Regel effizienter als zum Beispiel Java Programme.

Page 6: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 66

Warum C und C++?● Vergleich beim „Great Programming Language Shootout“

● siehe http://shootout.alioth.debian.org/

● C Code hier bis zu einem Faktor von 36 schneller als Java („mandelbrot“ Benchmark) und bis zu 23 mal kleiner.- Mit JIT Compiler ist Java deutlich schneller (als mit Interpreter)

aber auch deutlich größer.● C und C++ liegen dicht beieinander. C Code war etwas langsamer,

dafür aber kleiner als der äquivalente C++ Code.

Page 7: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 77

Und warum lieber nicht?● Undefiniertes Verhalten, z.B.

● Zugriffe über die Grenzen eines Arrays hinweg● Lesen einer uninitialisierten Variablen● Dereferenzieren eines Zeigers, der auf kein gültiges zum Typ des

Zeigers passendes Objekte verweist

● Manuelle Heap-Speicher-Verwaltung, z.B.● Memory Leaks● Ungültige Zeiger● Mehrfachfreigabe

● Portabilität, z.B.● Wertebereich von Objekten variiert je nach Compiler/Zielplattform

➔ Stabilitäts- und Sicherheitsprobleme, z.B.● Buffer Overflows können genutzt werden, um die Kontrolle über

privilegierte Programme zu übernehmen.

Page 8: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 88

Inhalt● Motivation

● Sicheres Programmieren in C und C++● MISRA C● Embedded C++● Cyclone

● Ressourcenverbrauch von C++ gegenüber C● Laufzeit-Polymorphie● Parametrische Polymorphie

● Zusammenfassung

Page 9: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 99

MISRA-C [2] (1)(Motor Industry Software Reliability Association)

● Über 100 Programmierregeln der Automobilindustrie● Vermeidung von undefiniertem Verhalten

● Einhaltung des Standards (ISO C)

● Guter Programmierstil zur Vermeidung von Fehlern und Missverständnissen

● Werkzeugunterstützung zur Überprüfung der Einhaltung● „MISRA-Checker“

● Statische Code-Analyse

● Weite Verbreitung in der Industrie● Compiler-Hersteller integrieren Checker● Integratoren verlangen die Einhaltung der Regeln von Zulieferern

Page 10: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1010

MISRA-C (2)● Beispiel

● Problem: Es können trotzdem diverse Fehler auftreten● Memory Leaks● Zugriffe über Array-Grenzen hinaus● …

➔ Nur der Stil wird verbessert, nicht die Sprache

Rule 34 (required)The operands of a logical && or || shall be primary expressions.

Invalid: if ( x == 0 && ishigh )Valid: if ( ( x == 0 ) && ishigh )

Primary expressions are constants, a single identifier such as ishigh, or a parenthesized expression. Parentheses are important for readability and ensuring that the behavior is what the programmer intends.

Rule 34 (required)The operands of a logical && or || shall be primary expressions.

Invalid: if ( x == 0 && ishigh )Valid: if ( ( x == 0 ) && ishigh )

Primary expressions are constants, a single identifier such as ishigh, or a parenthesized expression. Parentheses are important for readability and ensuring that the behavior is what the programmer intends.

Page 11: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1111

Embedded C++ (EC++)● Teilmenge von C++ für eingebettete Systeme

● Festgelegt von einem japanischen Industriekonsortium,u.a. Hitachi, NEC, Fujitsu, Toshiba

● Weglassen wurden ...● kostenbehaftete C++ Sprachmerkmale

- RTTI

- Exceptions

● komplexe Merkmale, die somit Fehlerquellen sind- Mehrfachvererbung (teils auch Kostengründe)

- Templates

- mutable-Qualifizierer

● Merkmale, die man einfach für unnötig hielt- Namespaces, New-style Casts

● Einige C++ Compiler erlauben Einschränkung auf EC++● oder auch nur EC++ (kein C++)

Page 12: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1212

Cyclone: Ein sicheres C [1]● C-Spracherweiterung, die undefiniertes Verhalten

vermeiden hilft.● Ein erweitertes Typsystem und statische Analyse

● Laufzeitabsicherungen

● Konkrete Maßnahmen● Spezielle sichere Zeigertypen (Fat, Thin und Bounded)

● Sicherer Umgang mit NULL

● Erzwungene Initialisierung

● Sichere Unions

● Region-based Type System

● Verschiedene Strategien zur Heap-Verwaltung (inkl. Garbage Coll.)

● Exceptions, Namespaces, Subtyping, u.v.m.

Page 13: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1313

Cyclone: Beispiele (1)● Fat Pointers

● Enthalten implizit den erlaubten Adressbereich● Dereferenzierungen außerhalb des Bereich führen zu Exception

#include <stdio.h>int main(int argc, char *@fat *@fat argv) { argc--; argv++; /* skip command name */ while (argc > 0) { printf(" %s",*argv); argc--; argv++; } printf("\n"); return 0;}

Das Speicher-Layout der Arrays ist nicht anders als bei C. Die fetten Zeiger enthalten die Information über die Dimension. Zeigerarithmetik ist erlaubt aber kontrolliert.

Das Speicher-Layout der Arrays ist nicht anders als bei C. Die fetten Zeiger enthalten die Information über die Dimension. Zeigerarithmetik ist erlaubt aber kontrolliert.

Page 14: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1414

Cyclone: Beispiele (2)● Thin Pointers

● Verweisen auf ein einzelnes Objekt● Es finden keine Laufzeitüberprüfungen statt● Zeigerarithmetik ist aber komplett verboten

● Garantierte Initialisierung● Realisiert durch statische Kontrollflussanalyse

int x = 3;int *y = &x;

Form *f;switch (event->eType) {case frmOpenEvent: f = FrmGetActiveForm(); ...case ctlSelectEvent: i = FrmGetObjectIndex(f, field); ...}

Fehler! 'f' ist hiernicht initialisiert.Fehler! 'f' ist hiernicht initialisiert.

Page 15: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1515

Cyclone: Beispiele (3)● Tagged Unions

● Optionale Erweiterung von Unions● Das Union-Objekt merkt sich seinen aktuellen Typ● Lesezugriffe werden kontrolliert● Der Typ kann auch explizit abgefragt werden

@tagged union U { int i; int *p; };void pr(union U x) { if (tagcheck(x.i)) printf("int(%d)",x.i); else printf("ptr(%d)",*x.p);}

Page 16: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1616

Cyclone: Kosten● Die Sicherheit hat ihren Preis

● Im Vergleich zu anderen sicheren Sprachen ist es jedoch effizient

Page 17: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1717

Fazit: Sichere/bessere C/C++ Dialekte● MISRA C und Embedded C++ reduzieren die

Fehlerwahrscheinlichkeit durch die Beschränkung auf eine Teilmenge von C bzw. C++.

● Der Compiler oder separate Werkzeuge können die Einhaltung der Regeln zur Übersetzungszeit prüfen

● Trotzdem bleiben viele zentrale Probleme bestehen

- Unsichere Zeiger, unkontrollierte Arrays, Manuelle Heap-Verwaltung, …

● Cyclone geht deutlich weiter

● Sichere Zeiger, Unions, Heap-Verwaltung, …

● Cyclone Programme sind typsicher und laufen ohne undefiniertes Verhalten durch.

Page 18: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1818

Inhalt● Motivation

● Sicheres Programmieren in C und C++● MISRA C● Embedded C++● Cyclone

● Ressourcenverbrauch von C++ gegenüber C● Laufzeit-Polymorphie● Parametrische Polymorphie

● Zusammenfassung

Page 19: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 1919

Was macht Objektorientierung aus?

● wesentliches Alleinstellungsmerkmal: Vererbung● im Fall von C++ sind zu untersuchen:

● einfach/mehrfach Vererbung

● virtuelles Vererben

● dynamisches Binden

Klassifizierung nach P. Wegner [3]:

object-oriented = data abstraction + abstract data types + type inheritance

Page 20: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2020

(Einfach-)Vererbung● eine abgeleitete Klasse erbt von einer Basisklasse

● geerbt werden Attribute, Methoden, ...

● statt einer Instanz der Basisklasse kannimmer auch eine Instanz der abgeleitetenKlasse verwendet werden

● gilt nicht umgekehrt!

● möglichst kompatibles Objekt-Layout

● Liskov'sches Substitutionsprinzip [4]

● Methoden können hinzugefügt oderüberdefiniert werden

Base

b1: int

b2: int

Derived

d: int

f: void ()

Page 21: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2121

(Einfach-)Vererbung – Ressourcen (1)

● die Attribute der Basisklasse liegen im Speicher am Anfang des Objekts

● keine Zeigeranpassung bei Typumwandlung von Base* in Derived* oder Derived* in Base* nötig

struct Base { int b1, b2;};

struct Derived : Base { int d; void f ();};

struct Base { int b1, b2;};

struct Derived : Base { int d; void f ();};

C++ Code der Klassen Objekt-Layout [5]

Base Instanz

Derived Instanz

this this

int b1int b2

int d

int b1int b2

Page 22: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2222

(Einfach-)Vererbung – Ressourcen (2)

● Methoden erhalten den this-Pointerals unsichtbaren ersten Parameter

● Zugriff auf eigene Attribute und Basisklassenattribute kosten gleich viel.

● Kein Overhead durch (Einfach-)Vererbung.

Derived derived;

int main () { derived.f ();}

void Derived::f () { b1 = 1; b2 = 2; d = 3;}

Derived derived;

int main () { derived.f ();}

void Derived::f () { b1 = 1; b2 = 2; d = 3;}

.bssderived: .zero 12

.bssderived: .zero 12

_ZN7Derived1fEv: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl $1, (%eax) movl $2, 4(%eax) movl $3, 8(%eax) popl %ebp ret

_ZN7Derived1fEv: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl $1, (%eax) movl $2, 4(%eax) movl $3, 8(%eax) popl %ebp ret

main: pushl %ebp movl %esp, %ebp pushl $derived call _ZN7Derived1fEv xorl %eax, %eax leave ret

main: pushl %ebp movl %esp, %ebp pushl $derived call _ZN7Derived1fEv xorl %eax, %eax leave ret

Page 23: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2323

Mehrfachvererbung

● eine abgeleitete Klasse erbt von mehreren Basisklassen

● eine auf dem „Einfachvererbungspfad“

● 1-N auf dem „Mehrfachvererbungspfad“

● Vererbungshierarchie ist keine Baumstruktur mehr

● mehrfaches Erben von der selben Klasse möglich!

Multi

m: int

fm: int ()

Single

s: int

fs: int ()

Derived

f: void ()

Page 24: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2424

Mehrfachvererbung – Ressourcen (1)

● die Attribute der Basisklassen liegen nacheinander im Speicher am Anfang des Objekts

● bei der Typumwandlung von Derived* in einen Zeiger auf eine Klasse im Mehrfachvererbungspfad muss ein Offset addiert werden

struct Single { int s; int fs();};

struct Multi { int m; int fm();};

struct Derived : Single, Multi /*, ...*/ { int f ();};

struct Single { int s; int fs();};

struct Multi { int m; int fm();};

struct Derived : Single, Multi /*, ...*/ { int f ();};

C++ Code der KlassenObjekt-Layout [3]

Derived Instanz

this (Derived)this (Single)

this (Multi)

∆S

......

int s

int m

Page 25: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2525

Mehrfachvererbung – Ressourcen (2)

● Beim Aufruf einer Methodeder Klasse im Einfach-vererbungspfad kann derthis-Pointer einfachdurchgereicht werden

● Beim Zugriff auf Multi muss this angepasst werden (+ 4)

● Bei inline-Methoden tritt das Problem nicht auf

● Geringer Overhead bei Mehrfachvererbung

void Derived::f () { fs (); fm ();}

void Derived::f () { fs (); fm ();}

_ZN7Derived1fEv: pushl %ebp movl %esp, %ebp pushl %ebx movl 8(%ebp), %ebx pushl %ebx call _ZN6Single2fsEv addl $4, %ebx pushl %ebx call _ZN5Multi2fmEv popl %eax movl -4(%ebp), %ebx popl %edx leave ret

_ZN7Derived1fEv: pushl %ebp movl %esp, %ebp pushl %ebx movl 8(%ebp), %ebx pushl %ebx call _ZN6Single2fsEv addl $4, %ebx pushl %ebx call _ZN5Multi2fmEv popl %eax movl -4(%ebp), %ebx popl %edx leave ret

Page 26: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2626

Virtuelle Vererbung● durch virtuelle Vererbung wird

vermieden, dass eine mehrfachgeerbte Basis mehr als einmalinstanziiert wird.

● Speicherplatz im Objekt wirdeingespart

● Mehrdeutigkeiten bei der Namens-auflösung werden vermieden

● Wo werden die Instanzen der virtuellen Basisklasse Common abgelegt?

Derived

f: void ()

Left

l: int

Right

r: int

Common

c: int

Page 27: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2727

Virtuelle Vererbung – Ressourcen (1)

● die Attribute virtueller Basisklassen liegen am Ende

● der Objekttyp-spezifische Offset macht die Typkonvertierung kompliziert

● (mindestens) eine virtuelle Funktionstabelle wird benötigt!

struct Common { int c; };

struct Left : virtual Common { int l;};

struct Right : virtual Common { int r;};

struct Derived : Left, Right { int d; void f ();};

struct Common { int c; };

struct Left : virtual Common { int l;};

struct Right : virtual Common { int r;};

struct Derived : Left, Right { int d; void f ();};

C++ Code der KlassenObjekt-Layout [3]

Derived Instanz

this (Derived)this (Left)

this (Common)

∆CDerived

VtableDerived

VtableDerived-

Rightint d

int l

int r

∆CDerived

∆CRightint c

Page 28: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2828

Virtuelle Vererbung – Ressourcen (2)

● Der Zugriff auf ein Attributeiner virtuellen Basisklasseist erheblich komplizierter

● Dazu kommen noch (in diesem Beispiel):● 90 Byte für Tabellen

● Konstruktor-Code zum Initialisieren der Vtable Zeiger

● Deutlicher Overhead bei virtueller Vererbung!● inbesondere, wenn die beteiligten Klassen sonst keine Vtable

benötigen würden

_ZN7Derived1fEv: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl (%eax), %edx movl -12(%edx), %edx movl $1, (%edx,%eax) movl $2, 4(%eax) movl $3, 12(%eax) movl $4, 16(%eax) popl %ebp ret

_ZN7Derived1fEv: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl (%eax), %edx movl -12(%edx), %edx movl $1, (%edx,%eax) movl $2, 4(%eax) movl $3, 12(%eax) movl $4, 16(%eax) popl %ebp ret

void Derived::f () { c = 1; l = 2; r = 3; d = 4;}

void Derived::f () { c = 1; l = 2; r = 3; d = 4;}

Page 29: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 2929

Dynamisches Binden● dynamisches Binden

erfolgt bei virtuellenFunktionen● C++ Schlüsselwort virtual

● die Zielfunktion einesAufrufs wird dabei zurLaufzeit ermittelt● wäre bv() nicht virtuell, würde in den Beispielen immer Base::bv() ausgeführt werden

● ob Base::bv() oder Derived::bv() ausgeführt wird, hängt vom Objekttyp (nicht vom Zeigertyp) ab

● da Base::b() sowohl auf Base als auch Derived Objekten ausgeführt werden kann, muss der Objekttyp ermittelt werden

● da nicht immer zur Übersetzungszeit bestimmt werden kann, worauf p in main() zeigt, muss auch hier der Typ ermittelt werden

Base

b: void ()

bv: void ()

Derived

bv: void ()

void Base::b () { bv ();} ?

int main () { Base *p = ...; p->bv ();} ?

Page 30: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3030

Dynamisches Binden – Ressourcen (1)

● die klassenspezifischen virtuellen Funktions-tabellen enthalten Zeiger auf den passenden Code

● der Konstruktor muss den Vtable Zeiger eintragen!

● ggf. sogar mehrfach überschreiben!

struct Base { void b (); virtual void bv () {}};

struct Derived : Base { void bv () {} // virtuell};

struct Base { void b (); virtual void bv () {}};

struct Derived : Base { void bv () {} // virtuell};

C++ Code der KlassenObjekt-Layout [3]

Derived Instanz

this (Derived)this (Base)

VtableDerived

VtableBaseBase Instanz

this (Base)

Base::bv()

Derived::bv()

Page 31: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3131

Dynamisches Binden – Ressourcen (2)

● Virtuelle Funktionsaufrufe wie inBase::b() und main() bedingen eine Indirektion● kein Inlining solcher Aufrufe möglich!● selbst leere virtuelle Funktionen müssen angelegt werden

● Dynamisches Binden kostet deutlich mehr als statisches!

main: pushl %ebp movl %esp, %ebp pushl $4 call _Znwj movl $_ZTV7Derived+8, (%eax) movl %eax, (%esp) call *_ZTV7Derived+8 xorl %eax, %eax leave ret

main: pushl %ebp movl %esp, %ebp pushl $4 call _Znwj movl $_ZTV7Derived+8, (%eax) movl %eax, (%esp) call *_ZTV7Derived+8 xorl %eax, %eax leave ret

int main () { Base *p = new Derived; p->bv();}

int main () { Base *p = new Derived; p->bv();}

void Base::b () { bv ();}

void Base::b () { bv ();}

_ZN4Base1bEv: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl (%eax), %edx pushl %eax call *(%edx) popl %eax leave ret

_ZN4Base1bEv: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl (%eax), %edx pushl %eax call *(%edx) popl %eax leave ret

_ZN4Base2bvEv: pushl %ebp movl %esp, %ebp popl %ebp ret

_ZN4Base2bvEv: pushl %ebp movl %esp, %ebp popl %ebp ret

Page 32: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3232

Kosten von Objektorientierung in C++● Einfachvererbung

● praktisch keine zusätzlichen Kosten

● Mehrfachvererbung

● Zeigerkonvertierung Mehrfachvererbungspfad, geringer Aufwand

● Virtuelle Vererbung

● Vtable Speicher, Objektinitialisierung, indirekter Zugriff, Aufwand!

● Dynamisches Binden

● Vtable Speicher, Objektinitialisierung, indirekter Aufruf, Aufwand!

● Faustregel: In ressourcenbeschränkten Domänen das virtual Schlüsselwort nur verwenden, wenn es wirklich nötig ist

Page 33: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3333

● Häufig werden die selben Algorithmen für verschiedene Datentypen benötigt, z.B. quicksort() für int, float, u.s.w. oder Listen von int, Foo oder Bar Objekten.

● Wie kann der Programmierer damit umgehen, z.B. in C oder Java < 5?

● Mehrfachimplementierung des Algorithmus- Probleme bei der Wartung, Wiederholung von Fehlern, Mühe!

● Gemeinsame Basis- fehlende Typsicherheit bzw. Typüberprüfung erst zur Laufzeit

● Präprozessoren (z.B. C Makros)- blinde Textersetzung, Scopes und Typen werden ignoriert

● Templates sind ein standardisierter [2] C++ Mechanismus, der alle diese Probleme vermeidet!

Warum Templates?

Page 34: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3434

● als Template-Parameter kann im Prinzip jeder Typ verwendet werden (keine gemeinsame Basis nötig!)

● Einschränkungen definiert das Template implizit, hier:● T benötigt operator < (const T&) const● die Aufrufparameter von max() müssen den selben Typ haben,

damit T „deduziert“ werden kann- int i = max(2,3); // ok

- int k = max(4,4.2); // Fehler

Ein erstes Funktions-Template

max.hmax.h

template <typename T>inline const T& max (const T &a, const T &b) { return a < b ? b : a;}

template <typename T>inline const T& max (const T &a, const T &b) { return a < b ? b : a;}

Template-Parameter (altern. <class T>)Template-Parameter (altern. <class T>)

T kann wie ein normaler Typverwendet werdenT kann wie ein normaler Typverwendet werden

Page 35: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3535

Überladen von Funktions-Templatesmax.hmax.h

template <typename T>inline const T& max (const T &a, const T &b) {...}

template <typename T>inline const T& max (const T &a, const T &b, const T &c) {...}

inline const int& max (const int &a, const int &b) {...}

template <typename T>inline const T& max (const T &a, const T &b) {...}

template <typename T>inline const T& max (const T &a, const T &b, const T &c) {...}

inline const int& max (const int &a, const int &b) {...}

main.ccmain.cc

#include “max.h“int main() { max(1,2,3); // Template mit 3 Argumenten max(1.0,2.0); // max<double> per Deduktion max('X','Y'); // max<char> per Deduktion max(1,2); // nicht-Template Variante bevorzugt max<>(1,2); // max<int> per Deduktion max<double>(1,2); // max<double> ohne Deduktion max('X',3.14); // nicht-Template Variante für 2 ints}

#include “max.h“int main() { max(1,2,3); // Template mit 3 Argumenten max(1.0,2.0); // max<double> per Deduktion max('X','Y'); // max<char> per Deduktion max(1,2); // nicht-Template Variante bevorzugt max<>(1,2); // max<int> per Deduktion max<double>(1,2); // max<double> ohne Deduktion max('X',3.14); // nicht-Template Variante für 2 ints}

Page 36: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3636

● Klassen-Templates sind perfekt für Container-Klassen● darum gibt es auch die Standard Template Library (STL)

Ein erstes Klassen-TemplateVector.hVector.h

template <typename T>class Vector { T *data; int dim;public: // Konstruktor, Copy-Konstruktor(!), ... // Zugriffsfunktionen z.B. mit Indexprüfung: void set (int index, const T& obj); T get (int index) const;};

template <typename T>class Vector { T *data; int dim;public: // Konstruktor, Copy-Konstruktor(!), ... // Zugriffsfunktionen z.B. mit Indexprüfung: void set (int index, const T& obj); T get (int index) const;};

main.ccmain.cc

#include “Vector.h“int main() { Vector<float> a_vector(3); a_vector.set (0, 2.71);}

#include “Vector.h“int main() { Vector<float> a_vector(3); a_vector.set (0, 2.71);}

Page 37: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3737

● Wenn Methoden von Klassen-Templates nicht im Klassenrumpf definiert werden, müssen sie ähnlich wie ein Funktions-Template formuliert werden:

Methoden von Klassen-Templates

vector.hvector.h

#include <assert.h>template <typename T>void Vector<T>::set (int index, const T& obj) { assert (index < dim); // wird nur in der Debug Variante // geprüft data[index] = obj; // erfordert operator = in T}

template <typename T>T Vector<T>::get (int index) { assert (index < dim); // wird nur in der Debug Variante // geprüft return data[index]; // erfordert Copy Konstructor}

#include <assert.h>template <typename T>void Vector<T>::set (int index, const T& obj) { assert (index < dim); // wird nur in der Debug Variante // geprüft data[index] = obj; // erfordert operator = in T}

template <typename T>T Vector<T>::get (int index) { assert (index < dim); // wird nur in der Debug Variante // geprüft return data[index]; // erfordert Copy Konstructor}

Page 38: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3838

● neben Typen können auch konstante Ausdrücke als Template-Parameter benutzt werden

Nicht-Typ Template-Parameter

Vector2.hVector2.h

template <typename T, int DIM>class Vector2 { T data[DIM]; // in jedem Objekt steckt ein Arraypublic: // Konstruktor, Copy-Konstruktor(!), ... // Zugriffsfunktionen z.B. mit Indexprüfung: void set (int index, const T& obj); T get (int index) const;};

template <typename T, int DIM>class Vector2 { T data[DIM]; // in jedem Objekt steckt ein Arraypublic: // Konstruktor, Copy-Konstruktor(!), ... // Zugriffsfunktionen z.B. mit Indexprüfung: void set (int index, const T& obj); T get (int index) const;};

● aber Achtung:

Vector<int> v1(10)Vector<int> v2(20); // v1 und v2 haben den selben TypVector2<int,10> v2_1; // v2_1 und v2_2 habenVector2<int,20> v2_2; // unterschiedliche Typen!

Vector<int> v1(10)Vector<int> v2(20); // v1 und v2 haben den selben TypVector2<int,10> v2_1; // v2_1 und v2_2 habenVector2<int,20> v2_2; // unterschiedliche Typen!

Page 39: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 3939

● Templates, die Templates benutzen sollen, können auch Templates als Parameter bekommen

Template Template-Parameter

DataCollector.hDataCollector.h

template <template <typename> class Container>class DataCollector { Container<double> collected_data; // Container wird benutztpublic: // ...};

template <template <typename> class Container>class DataCollector { Container<double> collected_data; // Container wird benutztpublic: // ...};

● so wird’s benutzt:

DataCollector<Vector> dc; // alles OK

DataCollector<Vector2> dc2; // geht nicht! // (Vector2 erwartet 2 Parameter)

DataCollector<Vector> dc; // alles OK

DataCollector<Vector2> dc2; // geht nicht! // (Vector2 erwartet 2 Parameter)

Parameter ist ein Template mit einem ParameterParameter ist ein Template mit einem Parameter

Page 40: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4040

● ähnlich wie bei Default-Argumenten von Funktionen können auch Template-Parameter ein Default haben● wie bei Funktionen müssen dann nachfolgende Parameter auch ein

Default haben

Default Template-Parameter

DataCollector2.hDataCollector2.h

template <template <typename,int> class Container=Vector2, int DIM=32>class DataCollector2 { Container<double, DIM> collected_data; // Container und DIMpublic: // ...};

template <template <typename,int> class Container=Vector2, int DIM=32>class DataCollector2 { Container<double, DIM> collected_data; // Container und DIMpublic: // ...};

● so wird’s benutzt:DataCollector2<> c1; // auf <> kann man nicht // verzichtenDataCollector2<Vector2> c2; // DIM ist 32 per DefaultDataCollector2<FooBar, 10> c3; // Default nicht genutzt

DataCollector2<> c1; // auf <> kann man nicht // verzichtenDataCollector2<Vector2> c2; // DIM ist 32 per DefaultDataCollector2<FooBar, 10> c3; // Default nicht genutzt

zwei Parameter mit Defaultszwei Parameter mit Defaults

Page 41: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4141

● mit Hilfe der Template Spezialisierung können unterschiedliche Template Implementierungen in Abhängigkeit von den Parametern gewählt werden

● Explizite Template Spezialisierung● für einen bestimmten Parametersatz, z.B. Vector<bool>

● Partielle Template Spezialisierung● für eine Parametermenge, z.B. Vector<const T*> mit beliebigem T● geht nicht bei Funktions-Templates

● wenn sowohl eine explizite als auch eine partielle Spezialisierung passen, wird die explizite gewählt

● passt keine Spezialisierung, wird das primäre Template genommen

● Template-Spezialisierung bewirkt eine Fallunterscheidung● wichtige Grundlage für Template-Metaprogrammierung

Template Spezialisierung

Page 42: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4242

● kann z.B. zur Optimierung benutzt werden:

Explizite Template Spezialisierung

● mit der Spezialisierung für bool wird für Vector<bool> auf dem Heap nur ein Achtel des Speicherplatzes angefordert

Vector.hVector.h

template <>class Vector<bool> { unsigned *data; // bool wird als Bit gespeichert int dim;public: // Konstruktor Vector(int d) { data = new unsigned[1 + (d-1) / (sizeof(unsigned)*8)]; } // Copy-Konstruktor(!), Zugriffsfunktionen, ...};

template <>class Vector<bool> { unsigned *data; // bool wird als Bit gespeichert int dim;public: // Konstruktor Vector(int d) { data = new unsigned[1 + (d-1) / (sizeof(unsigned)*8)]; } // Copy-Konstruktor(!), Zugriffsfunktionen, ...};

explizite Spezialisierung für boolexplizite Spezialisierung für bool

Page 43: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4343

● kann z.B. die gleiche Optimierung für Vector2 realisieren:

Partielle Template Spezialisierung

Vector2.hVector2.h

template <int DIM>class Vector2<bool, DIM> { typedef unsigned storage_t; static const unsigned BITS = sizeof(storage_t) * 8; storage_t data[1 + (DIM - 1) / BITS];public: // Konstruktor, Copy-Konstruktor(!), ... // Zugriffsfunktionen z.B. mit Indexprüfung: void set (int index, bool obj) { if (obj) data[index / BITS] |= (1 << (index % BITS)); else data[index / BITS] &= ~(1 << (index % BITS)); } // ...};

template <int DIM>class Vector2<bool, DIM> { typedef unsigned storage_t; static const unsigned BITS = sizeof(storage_t) * 8; storage_t data[1 + (DIM - 1) / BITS];public: // Konstruktor, Copy-Konstruktor(!), ... // Zugriffsfunktionen z.B. mit Indexprüfung: void set (int index, bool obj) { if (obj) data[index / BITS] |= (1 << (index % BITS)); else data[index / BITS] &= ~(1 << (index % BITS)); } // ...};

partielle Spezialisierung für bool und beliebige DIMensionpartielle Spezialisierung für bool und beliebige DIMension

Page 44: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4444

Ressourcenverbrauch von Templates● Bei Inline-Funktionen effizient wie Makros, aber typsicher

● Gefahr des Code Bloat● Auswirkung auf die Codegröße und weniger auf die Performance

testmax.cctestmax.cc

template <typename T>inline const T& max (const T &a, const T &b) { return a < b ? b : a;}

int f() { return max (3, max (1, 2)); }

template <typename T>inline const T& max (const T &a, const T &b) { return a < b ? b : a;}

int f() { return max (3, max (1, 2)); }

_Z1fv: push %ebp mov $0x3,%eax mov %esp,%ebp pop %ebp ret

_Z1fv: push %ebp mov $0x3,%eax mov %esp,%ebp pop %ebp ret

<int const& max<int>(int const&, int const &)>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 4d 08 mov 0x8(%ebp),%ecx 6: 8b 55 0c mov 0xc(%ebp),%edx 9: 8b 01 mov (%ecx),%eax b: 3b 02 cmp (%edx),%eax d: 7c 02 jl 11 f: 89 ca mov %ecx,%edx 11: 89 d0 mov %edx,%eax 13: 5d pop %ebp 14: c3 ret

<int const& max<int>(int const&, int const &)>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 4d 08 mov 0x8(%ebp),%ecx 6: 8b 55 0c mov 0xc(%ebp),%edx 9: 8b 01 mov (%ecx),%eax b: 3b 02 cmp (%edx),%eax d: 7c 02 jl 11 f: 89 ca mov %ecx,%edx 11: 89 d0 mov %edx,%eax 13: 5d pop %ebp 14: c3 ret

<long const& max<long>(long const&, long const &)>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 4d 08 mov 0x8(%ebp),%ecx 6: 8b 55 0c mov 0xc(%ebp),%edx 9: 8b 01 mov (%ecx),%eax b: 3b 02 cmp (%edx),%eax d: 7c 02 jl 11 f: 89 ca mov %ecx,%edx 11: 89 d0 mov %edx,%eax 13: 5d pop %ebp 14: c3 ret

<long const& max<long>(long const&, long const &)>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 4d 08 mov 0x8(%ebp),%ecx 6: 8b 55 0c mov 0xc(%ebp),%edx 9: 8b 01 mov (%ecx),%eax b: 3b 02 cmp (%edx),%eax d: 7c 02 jl 11 f: 89 ca mov %ecx,%edx 11: 89 d0 mov %edx,%eax 13: 5d pop %ebp 14: c3 ret

identis

ch!

Page 45: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4545

Inhalt● Motivation

● Sicheres Programmieren in C und C++● MISRA C● Embedded C++● Cyclone

● Ressourcenverbrauch von C++ gegenüber C● Laufzeit-Polymorphie● Parametrische Polymorphie

● Zusammenfassung

Page 46: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4646

Zusammenfassung● C und C++ sind nicht typsicher

● Quelle für diverse Fehler und Sicherheitslücken● Teilmengen wie MISRA C und Embedded C++ helfen nur bedingt

● Dafür bieten C und C++ …● (Kosten-)transparenz

- Man „sieht“ wofür die Ressourcen verbraucht werden

- Das Systemverhalten ist vorhersagbar (z.B. kein Garbage Collector)

● Kontrolle über den Ressourcenverbrauch- Man kann den Ressourcenverbrauch beeinflussen (tuning)

… und sind daher dominierend in eingebetteten Systemen● C++ erweitert C primär um zwei neue Paradigmen

● Objektorientierung- Vorsicht Kostenfalle

● Generische Programmierung- Komplex, aber keine Laufzeitkosten → geeignet für eingeb. Produktlinien

Page 47: Software ubiquitärer Systeme · 1 Software ubiquitärer Systeme Anwendungsentwicklung in C/C++ Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12

06.1 – Anwendungsentwicklung in C/C++ 4747

Literatur[1] T. Jim, J. G. Morrisett, D. Grossman, M. W. Hicks, J. Cheney,

and Y. Wang. Cyclone: A Safe Dialect of C. In Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference (C. S. Ellis, Ed.). USENIX Association, Berkeley, CA, pages 275-288, June 2002.

[2] Guidelines for the Use of the C Language in Critical Systems, ISBN 0 9524156 2 3 (paperback), ISBN 0 9524156 4 X (PDF), October 2004.

[3] P. Wegner. Classification in Object-Oriented Systems, ACM, SIGPLAN Notices, 21(10):173-182, 1986.

[4] B. Liskov. Data Abstraction and Hierarchy, ACM, SIGPLAN Notices, 23(5), 1988.

[5] C++ ABI Summary, http://www.codesourcery.com/cxx-abi