Inhalt
Topic:LibJc.ctor
Instanzen können in C angelegt werden:
im heap: Mittels os_malloc(size), alloc_MemC(size) oder alloc_ObjectJc(size,...),
statisch global: Type instance
außerhalb von Routinen,
im Stack: Type instance
innerhalb von Routinen,
als Bestandteil anderer Instanzen (embedded instances/objects).
Die Möglichkeit, innerhalb von Routinen mittels static
einmalige Instanzen anzulegen, soll hier nicht betrachtet und auch nicht empfohlen werden. Die embedded objects sind hier extra aufgeführt, die umfassende Instanz wird nach einer der drei darüberstehenden Möglichkeiten instanziiert.
Der Grund: Eingebettete Instanzen benötigen eigene Regeln zur Initialisierung.
In allen Fällen sollte eine Grundinitialisierung unabhängig von der Funktionalität der angelegten Instanz erfolgen. Ziel dieser Initialisierung ist es einerseits, undefinierte Speicherbelegungen zu vermeiden. Andererseits enthalten die von von ObjectJc abgeleitete Instanzen allgemein eintragbare Verwaltungsinformationen:
Der Speicher soll mit 0 vorbesetzt sein.
In ObjectJc kann eine Initialisierung des Elementes objectIdentSize
mindestens bezüglich der Größenangabe des zugehörigen Speicherplatzes erfolgen.
In ObjectJc kann die eigene Adresse eingetragen werden. Die eigene Adresse kann zu Kontroll-Zwecken (checkConsistence_ObjectJc(...)) verwendet werden, oder als Instanzerkennung bei Transport von Daten in ein anderes Medium.
Diese Initialisierungen sollten so früh wie möglich erfolgen, unmittelbar an der Stelle, an der die betreffenden Informationen primär bekannt sind. Damit werden Fehler vermieden.
Topic:LibJc.ctor.codeInit
Topic:LibJc.ctor.codeInit.ctor
Topic:LibJc.ctor.codeInit.static
ctor
Topic:LibJc.ctor.codeInit.static.definition
Statische Instanzen werden als Daten in einem Speicherbereich definiert. Der Speicherbereich ist fester Bestandteil des Ladeobjektes. Wo dieser Speicherbereich liegt, wird beim Linken bereits festgelegt. Erfolgt ein statisches Laden, dann liegt beim Linken, also unabhängig von einer Hardware oder einem Betriebssystem sogar die Speicheradresse endgültig fest. Das hat Bedeutung für kleinere Prozessoren. Damit ist auch eine Notwendigkeit von statischen Instanzen begründbar: Es kann ein bestimmter Speicherbereich, beispielsweise mit bestimmten Eigenschaften wie Dual-Port-RAM oder Batteriepufferung, oder mit bestimmten Zugriffsmöglichkeiten: ROM, RAM mit bestimmter Zugriffszeit oder dergleichen bestimmt werden.
In C oder C++ wird eine statische Instanz einfach außerhalb von Routinen festgelegt:
Typ name = {0};
Die Information, wo diese Instanz liegt, kann beim Compilieren und Linken festgelegt werden:Mittels Angabe eines bestimmten Segmentnamens beim Compilieren, und dann mittels Angabe des Speicherbereiches des Segmentes beim Linken.
Topic:LibJc.ctor.codeInit.static.staticInit
Die Null-Initialisierung, immer einfach schreibbar mit {0}
sollte Pflicht sein. Damit wird eine zufällige Speicherbelegung vermieden. Das Schreiben von 0-Bytes wird entweder beim Hochlauf
vor Aufruf von main erledigt, oder es ist im Ladeobjekt verankert und wird also beim Laden des Programmes erledigt. Eine Initialisierung
in {...}
mit bestimmten Werten ist möglich, wird aber nicht empfohlen: Die Initialwerte sind oft nicht konstant und können daher mindestens
in C nicht in dieser Art vorbesetzt werden. Eine Teilung, Konstante Werte in {...}
vorbesetzen, den Rest in einer Initialisierungsroutine (Konstruktor), ist gegebenenfalls keine gute Sache weil dem Überblick
nicht dienlich. Zudem ist die Schreibweise in {...}
bei komplexen Strukturen nicht einfach, man kann sich verzählen, schwer kontrollieren ...:-(. Das Einschreiben der konstanten
Werte in einer Intialisierungsroutine/Konstruktor ist kaum ein Aufwand. Es sei denn, mann möchte bestimmte Werte mit const
bezeichnet wissen. In C muss man diese dann in {...}
initialisieren. In C++ kann das der C++-Konstruktor bei Angabe in der sogenannten Initialsierungsliste. Es könnte sein, dass
es günstiger ist, auf spezielle const
-Elemente zu verzichten. Der Preis ist keine Kontrolle versehentlich programmierter Schreibbefehle vom Compiler, nichts anderes.
Der Preis ist ausgleichbar damit, dass man insgesamt in der Software gekapselt vorgeht, die struct
-Definitionen nur dort bekannt macht, wo man sie selbst braucht. Das ist ein adquates Prinzip zu Java bzw. ein Prinzip der
Objektorientierung.
Topic:LibJc.ctor.codeInit.static.initObjectJc
Die Initialisierung der ObjectJc-Basisdaten einer statischen Instanz soll über ein Aufruf von
init_ObjectJc(&instance.object, size, typeIdentInfo)
während der Hochlaufphase in main()
erfolgen. Der erste Parameter ist der Zeiger auf die ObjectJc-Basisstruktur der Instanz, die am Anfang liegen sollte. size
ist mit sizeof(Typ)
oder besser noch mit sizeof(instanceName)
schreibbar, damit erfolgt kontrolliebar die richtige Größenangabe. Der Compiler ermittelt daraus eine einfache Konstante.
Der Wert typeIdentInfo
dient der Kennzeichnung für Debugzwecke, oder gegebenenfalls für einen Datenaustauch. Man kann hier auch 0
notieren.
Eine damit initialisierte Instanz kann danach einem Konstruktor ctorO...
des Zieltypes mit Parametern zugeführt werden.
Topic:LibJc.ctor.codeInit.embedded
Embedded objects müssen bezüglich der Initialisierung ähnlich behandelt werden wie statische Instanzen. Das liegt daran, dass der Speicherplatz
mit Anlage der umfassenden Instanz einfach mal da ist, ähnlich wie er be statischen Instanzen eben da ist, sobald er definiert
ist. Da die Regel besteht, dass alle Instanzen grundsätzlich mit 0 vorbesetzt sind, wird eine eingebettete Instanz zunächst
als nur mit 0 gefüllt vorgefunden. Handelt es sich um eine Instanz von ObjectJc abgeleitet, dann muss also vor Aufruf des
ctorO...;;-Konstruktors der ObjectJc-Anteil initialisiert werden. Das erfolgt genau wie bei statischen Instanzen mit dem Aufruf
von
init_ObjectJc(
Topic:LibJc.ctor.codeInit.noObject
os_malloc(size)
allokiert im vom Betriebssystem bereitgestelltem Heap und nimmt keine Initialisierungen vor. Diese Routinen sollte nicht
vom Anwender gerufen werden, sie ist der Betriebssystemanpassung vorbehalten! * alloc_MemC(int size) initialisiert den Speicher mit 0. Da mit dem Aufruf die allokierte Bytenanzahl zurückgegeben wird (innerhalb MemC), ist die Längeninformation zusammen mit der Speicheradresse in einem Objekt gebunden, damit geeignet zur einfachen Weitergabe.
alloc:MemC(int)
ist daher geeignet für Initialisierung von Instanzen insbesondere oder gegebenenfalls ausschließlich in der Hochlaufphase,
die nicht von ObjectJc abgeleitet sind. Der Anwender sollte unmittelbar danach initial notwendige Daten eintragen.
Topic:LibJc.ctor.codeInit.objectJc
Aufruf der Anlage und Initialisierung
Die Initialisierung wird/soll wie folgt vorgenommen werden:
alloc_ObjectJc(...) allokiert im Heap, zur Laufzeit gegebenenfalls in einem Blockheap, und nimmt die oben genannten Initialisierungen der ObjectJc-Basisdaten vor.
Eine statische Instanz, die nicht von Object abgeleitet ist, sollte immer mit = {0}
unmittelbar in der Vereinbarungszeile initialisiert werden.
Erstellt 2008-12-20, Erstentwurf