Kodieräffchen
Thursday, November 06, 2003
 
Vorkompilierte Header - stdafx.h
(precompiled header)

"Vorkompilierte Header" beschleunigen die Übersetzung. Dazu sollte stdafx.h Header_Dateien einbinden, die in den meisten Projektdateien vorhanden sind und sich nicht (oder nur selten) verändern.

Hintergrund:
Wenn ein C++-Programm übersetzt wird, nimmt der Compiler sich jede CPP-Datei einzeln vor, und übersetzt das, was drin steht. der Linker bindet dann die "Ergebnisse" jeder .cpp - Datei zu einer .exe (oder .dll oder was auch immer) zusammen. #include's funktionieren dabei wie reiner Textersatz.

Wenn man mit größeren Bibliotheken (z.B. der WinAPI oder der MFC) arbeitet, müssen für jede .cpp-Datei eine Menge Header-Dateien abgearbeitet werden. Um das zu beschleunigen, gibt es vorkompilierte Header: Der Compiler merkt sich die kompletten Symboltabellen der Header-Dateien, und muß die #includes nicht wiederholt abarbeiten. Das geht natürlich nur, wenn die Header in der gleichen Reihenfolge (und mit absolut identischen voranstehenden Deklarationen, #defines usw.) #includiert werden.

Diese Symboltabellen werden aber ziemlich groß (.pch bei C++, ein paar MB für ein Windows/MFC - Projekt), von daher sind dem vorkompilieren Mengengrenzen gesetzt.

Visual C++ macht nun (mit den Assistenten-Standardeinstellungen) folgendes:



ACHTUNG: zumindest VC6 ignoriert z.B. #defines vor dem #include "stdafx.h" völlig!

Da damit stdafx.h als allerersteDatei in allen .cpp - Dateien #includiert werden muß, ist es auch ein bequemer Platz um globale Projektdefinitionen unterzubringen.
Friday, October 31, 2003
 
Implementation, Schnittstelle und Vertrag
Die erste Lektion - eine der wichtigsten: Lerne Vertrag, Schnittstelle und Implementation zu unterscheiden!

Zu jeder Funktion, jeder Klasse gehören:


Ein Beispiel:
char * minstr(char * a, char * b) 
{
if (strcmp(a,b) <= 0)
return a;
else
return b;
};


Vertrag: minstr gibt einen Zeiger auf den (nach ASCII) kleineren String von a und b. a und b sind Zeiger auf NUL-Terminierte Strings und dürfen nicht NULL sein.

Deklaration:minstr empfängt zwei Zeiger auf char und gibt einen Zeiger auf char zurück

Implementation: Man könnte sich ja darauf verlassen daß zeile 3 "<=" verwendet anstatt "<" - daß also bei identischen Strings immer ein Zeiger auf den ersten zurückgegeben wird. Das funktioniert aber nur solange, bis jemand der Meinung ist, das ein "<" den Vertrag genauso gut erfüllt, und dies stillschweigend ändert. Oft werden solche Angaben im Vertrag nicht erwähnt oder als "implementationsspezifisch" markiert, Es besteht also eine gewisse Freiheit in der Implementation.

Warum ist das wichtig:
Moderne Anwendungen arbeiten mit einer Vielzahl von Bibliotheken und APIs, die während der lebenszeit der Anwendung weiterentwickelt werden. Oft mu߸ die Anwendung mit verschiedenen versionen der API's zusammenarbeiten - z.B. auf Windows 98 und Windows XP.

Das gilt genauso für eigene Bibliotheken, selbst für einen einzelnen Programmierer, wenn das Projekt nur groß genug wird.

Man kann sich nur auf den Vertrag verlassen, nicth auf die aktuelle Implementation. Solange probieren bis es geht gilt nicht!



Powered by Blogger