HOWTO zum Unterschieden Systeme/Programmiersprachen
(C) 2007 T.Birnthaler/H.Gottschalk <howtos(at)ostc.de>
OSTC GmbH, www.ostc.de
$Id: hwsw-differences-HOWTO.txt,v 1.9 2009-08-12 16:06:23 tsbirn Exp $
Dieses Dokument beschreibt die Hardware- und Software-Unterschiede
diverser Rechnersystem und Programmiersprachen.
1) Einführung
2) Programmiermodell/Compiler/Software-Unterschiede
3) Hardware-Unterschiede
Zwischen Rechner-Hardware (PC, UNIX-Workstation, HOST) und Programmiersprachen
(C, Perl, COBOL, Assembler) gibt es viele Unterschiede, die beim Transfer von
Programm-Quellcode und von Daten (auch über Netzwerk!) zwischen Rechnern und
beim Kombinieren unterschiedlicher Programmiersprachen zu einem Programm
auf einem Rechner zu berücksichtigen sind.
HINWEIS: Beim Austausch von Daten über eine Datenbank bestehen obige Probleme
normalerweise nicht. Eine Datenbank legt die Daten sowieso in einem eigenen
Format ab. Beim Lesen/Schreiben von Daten aus/in eine Datenbank wird durch die
jeweilige API (Application Programmers Interface) zwischen dem
datenbankspezifischen Format und dem Format der konkreten Hardware-Plattform
bzw. dem der konkreten Programmiersprache konvertiert.
* Zeichencodierung
+ Dos/Windows: ASCII (8 Bit) bzw. Latin1 (8 Bit) bzw. UCS-2 (Unicode, 2 Byte)
+ Linux/Unix: ASCII (8 Bit) bzw. Latin1 (8 Bit) bzw. UTF-8 (Unicode, 1-4 Byte)
+ HOST: EBCDIC (7 Bit)
* Zeilenenden in Textdateien
+ Unix/Linux: Zeilenende = \n (nur Newline = Linefeed = 10)
+ Dos/Windows: Zeilenende = \r\n (Carriage Retuern = 13 + Newline = 10)
+ Mac: Zeilenende = \r (nur Carriage Return = 13)
+ HOST: a) Feste Zeilenlänge, mit Leerzeichen aufgefüllt
b) 2/4 Byte Satzlänge vor jedem Satz
* Dateiende bei Textdateien (bei Eingaben auf Kommandozeile)
+ Dos/Windows: Strg-Z (veraltet, aber kommt noch in Dateien vor)
+ Unix/Linux: Strg-D (steht nicht in Datei, nur bei Eingaben)
+ Mac:
+ HOST:
* Reihenfolge der Funktionsparameter bei einem Funktionsaufruf
+ C: Von "links nach rechts" (da variabel lange Listen möglich)
+ COBOL/ASS: Von "rechts nach links" (effizienter)
* Wer räumt Stack am Ende eines Funktionsaufrufes auf
+ C: Aufgerufene Funktion
+ COBOL/ASS: Aufrufer
* Darstellung von Strings im Speicher
+ C: String variabler Länge, danach NUL-Byte Begrenzung
(Länge implizit, Speicherbedarf um 1 größer, KEIN 0-Byte mögl.)
+ Perl: 4 Byte Länge (wo?) + String variabler Länge (0-Byte erlaubt)
+ COBOL/ASS: Fixe Länge + mit Leerzeichen aufgefüllt
(Länge woanders hinterlegt, Speicherbedarf immer gleich)
+ HOST: 2/4 Byte Länge am Anfang + danach String variable Länge
(Länge explizit, Speicherbedarf um 2/4 Byte größer)
+ PASCAL: 1/2 Byte Länge am Anfang + danach String variable Länge
(Länge explizit, Speicherbedarf um 1/2 Byte größer)
* Zahlendarstellung Binärzahlen <-> BCD-Zahlen (Binary Coded Digits)
+ C: Binäre Codierung (Vorzeichen + Mantisse + Exponent)
Wissenschaftliche Anwendungen, möglichst viele Stellen
+ COBOL: BCD-Codierung (Vorzeichen + Vorkommateil + Komma + Nachkommateil)
Kaufmännische Anwendungen, keine Darstellungsfehler im 10er-System
* Zahlendarstellung Festkomma <-> Fließkomma
+ C: Anzahl Vor- und Nachkommstellen variabel
("wissenschaftliche Art", Komma "wandert", IEEE-Standard)
+ COBOL/ASS: Anzahl Vor- und Nachkommstellen fix ("kaufmännische Art")
(BCD-Darstellung)
* "Breite" von Zahlen
+ C: Fixer Set von Ganzzahl-Datentypen (char, short, int, long)
und Fließkomma-Datentypen (float, double)
Breite von int/long von Prozessor-Wortbreite abhängig
float/double nach IEEE-Norm = identisch auf allen Plattformen
+ COBOL/ASS: Definierbare Breite von Zahlen (Anzahl Vor+Nachkommastellen)
da als BCD-Zahlen dargestellt
* Globale Variablen <-> Lokale Variablen
+ C: Globale + Lokale Variablen (Stack)
Statische + Dynamische Variable (Heap)
Schutz gegen versehentlichen Zugriff
+ COBOL/ASS: Parameterleiste = Globale Variablen
Kein Schutz gegen versehentlichen Zugriff
* Zeiger (Pointer) typisiert bzw. nicht typisiert:
+ C: Zeiger sind typisiert, d.h. "wissen" worauf sie zeigen
(Compiler überprüft korrekte Verwendung außer bei Casts)
+ COBOL/ASS: Zeiger sind untypisiert, d.h. "wissen nicht" worauf sie zeigen
Obige Punkte sind während EINES Programmlaufs kritisch, wenn Daten zwischen
unterschiedlichen Programmiersprachen/Compilern ausgetauscht werden, die z.B.
zu einem Executable oder einer Phase zusammengelinkt/gebunden wurden.
Auf unterschiedlichen Hardware-Plattformen kann es folgende Unterschiede geben
(z.B. Intel-Prozessor <-> SPARC/MIPS/HOST-Prozessor):
* Anordnung der Bytes im Speicher bei Datentypen mit mehr als 1 Byte Länge
(sogenannter Byte-Sex: "Little-Endian" <-> "Big-Endian")
+ i386: Niedrigwertigstes Byte an Speicherstelle mit niedrigster Adresse
+ HOST: Höchstwertigstes Byte an Speicherstelle mit niedrigster Adresse
Zahl (4 Byte) i i+1 i+2 i+3 Speicheradresse
+------+------+------+------+
0x44332211 => | 0x11 | 0x22 | 0x33 | 0x44 | Intel-Prozessor (Little-E.)
+------+------+------+------+
0x44332211 => | 0x44 | 0x33 | 0x22 | 0x11 | HOST-Prozessor (Big-E.)
+------+------+------+------+
Dies betrifft z.B. auch IP-Adressen, die im 1. Fall als 192.168.1.2 im
Speicher abgelegt werden, im 2. Fall als 2.1.168.192.
* Binäre Ganzzahlendarstellung (insbesondere negative Zahlen)
+ Einer-Komplement: -N = N mit allen Bits gekippt
(symmetrisch, zwei Nullwerte)
+ Zweier-Komplement: -N = N mit allen Bits gekippt + 1
(asymmetrisch, ein Nullwert)
+ Inzwischen fast nur noch Variante 2 verwendet, Variante 1 ist veraltet.
Obige beiden Probleme sind nicht während EINES Programmlaufs kritisch, sondern
nur dann, wenn solche Daten auf Platte gespeichert und wieder gelesen werden
oder über Netzwerk ausgetauscht werden. Dann muss man die Daten in die eine
oder andere Richtung konvertieren (z.B. mit Hilfe des altbekannten Verfahrens
XDR = eXternal Data Representation von SUN, das in Form von Bibliotheken
verfügbar sein sollte) oder man konvertiert durch Byte-Tausch selbst.
Allerdings kann man die Darstellung nicht am "Strom der binären Daten" selbst
ablesen, diese sind ja nur Bitmuster ohne Typinformation. Sondern man muss
"wissen", was die gerade transferierten Bytes bedeuten. D.h. welche Anzahl von
Bytes ein "Objekt" (String, Integer, Float, Struktur, ...) darstellt und
welchen Datentyp dieses Objekt repräsentiert. D.h. man muss eine
Strukturbeschreibung der "Objekte" auf beiden Plattformen haben.
HINWEIS: Beim Austausch von Daten über eine Datenbank bestehen die beiden
obigen Probleme normalerweise ebenfalls nicht.