Diskussion:Microsoft C

aus Wikipedia, der freien Enzyklopädie
Letzter Kommentar: vor 4 Monaten von 84.158.120.82 in Abschnitt ANSI C Kompatibilität
Zur Navigation springen Zur Suche springen

Benennung der Speichermodelle

[Quelltext bearbeiten]

Im Artikel heißt es:

Die Speichermodelle von Lattice C wurden durch die Intel-x86-Speichermodelle (vgl. Speichermodelle von Turbo C) ersetzt.

der Vergleich zu Turbo C könnte dem Leser suggerieren, dass Microsoft die Namen von Borland übernommen hat. Die eigentliche Quelle für die Benennung der Speichermodelle dürfte meiner Meinung nach aber eher von MASM, also Microsofts Assembler, stammen. Es wäre jedenfalls sehr naheliegend. --93.229.175.119 19:47, 29. Mai 2024 (CEST)Beantworten

Naja, genau deshalb habe ich nicht direkt verlinkt, sondern ein vgl. davor geschrieben. Die Tabelle in Turbo C ist die älteste Auflistung der Speichermodelle, da es sie zuvor nirgendwo sonst gab. Inzwischen kann man sie in den Artikel Segmentierung (Speicherverwaltung)#Speichermodell verschieben (gab's damals noch nicht). Ebenso die Erklärung von FAR und NEAR, die es im TC-Artikel ebenfalls erstmals zu lesen gab.
Einzige Ausklammerung ist das Flat-Modell, das im Artikel Segmentierung (Speicherverwaltung) zusätzlich genannt wird. Das wurde erst später eingeführt und gilt nicht für die alten TC (und div. andere) Compiler.
=> Was hältst Du von diesem Plan:
  1. Die leere Tabelle im Segmentierungsartikel durch die volle Tabelle aus TC ersetzen.
  2. FAR/NEAR Satz ebenfalls dorthin verschieben bzw. kopieren.
  3. Flat-Modell anfügen (ggf. irgendwie farblich hinterlegen oder schraffieren).
  4. Im TC- und hier im MC-Artikel auf den Segmentierungsartikel verlinken.
Fertig. --Siegbert v2 (Diskussion) 10:00, 30. Mai 2024 (CEST)Beantworten
Das in Segmentierung (Speicherverwaltung)#Speichermodell war ich, das habe ich vor ein paar Wochen in den Artikel einbaut.
Was hältst du von folgender Umbenennung des obigen Satzes in:
Die Speichermodelle von Lattice C wurden durch die Intel-x86-Speichermodelle ersetzt, wie sie auch in MASM üblich sind. (Siehe dazu auch Segmentierung (Speicherverwaltung)#Speichermodell)
Zum Thema übertragen der Tabelle aus dem Turbo C Artikel in den Segmentierungsartikel. Die Tabelle müsste man dazu etwas überarbeiten. Überall, wo bspw. 1 MiB als Größenangabe vorkommt, müsste man das durch "mehrere 64 KiB Segmente" ersetzen, denn der Speicher ist hier kein 1 MiB großes zusammenhängendes Stück, sondern es sind nur mehrere einzelne Segmente, die jeweils maximal nur 64 KiB groß sein können. Das wird gerade in der Assemblerprogrammierung sehr deutlich, dass man es hier mit mehreren Segmenten zu tun hat. Bei Hochsprachen wie C kann es sein, dass die Sprache das alles abstrahiert und einem das als 1 MiB großes Stück erscheinen lässt, aber in Assembler ist das gerade nicht so. Real sind es nur mehrere 64 KiB Segmente. Dazu kommt noch, dass in Assembler sich diese Segmente auch überlappen dürfen, das würde beim Codesegment dann Platz sparen, da man dann mit Near Zeigern darauf zugreifen könnte. Auch bin ich mir jetzt nicht sicher, ob man überhaupt 1 MiB schreiben kann. Der 20 Bit große Adressraum würde es zwar erlauben, aber der in DOS nutzbare konventionelle Speicher geht nur bis 640 KiB, der Rest darüber, also der UMB ist für die Harwdare reserviert. Damit hätte man also bestenfalls nur 10 Stück x 64 KiB Segmente minus 1 Segment, das man dann je nach Speichermodell für den Code oder die Daten benötigt. Verkompliziert wird das dann mit so Möglichkeiten wie Expanded Memory (EMS), der es erlaubt, aus Speicherkarten oder Speicherbereichen oberhalb der HMA weiteren Speicher anzusprechen und diesen im UMB Bereich als maximal 64 KiB großes EMS Fenster einzublenden. Dieser EMS Speicher kann nur für Daten benutzt werden, nicht aber für Code.
Auch fällt mir auf, dass die Tabelle noch für Turbo C spezifische Feinheiten erhält, z.B. steht beim Compact Modell
Per Voreinstellung sind alle Funktionen und alle Datenzeiger Far.
In Assembler könnte man Far und Near Zeiger mischen, je nachdem, ob man gerade nur in einem Datensegment arbeitet oder datensegmentübergreifend Daten abrufen muss. Near Zeiger sind kürzer, sie sparen damit Speicherplatz im Programmcode und schneller sind sie dadurch beim Dekodieren auch. Aus Assemblersicht macht es daher Sinn, die Farzeiger nur dann zu benutzen, wenn man sie wirklich benötigt und ansonsten mit Nearzeigern zu arbeiten. Auch ist es in Assembler erlaubt, die Segmentadresse einfach zu verschieben, wenn die Daten als zusammenhängendes Stück verfügbar sind, dann reichen auch wieder nur Nearzeiger.
Beim Tiny Modell müsste man noch den Teil hinzufügen, der bereits im Segmentierung (Speicherverwaltung) Artikel steht. Nämlich, dass das Tiny Modell aus Abwärtskompatibilitätsgründen zu CP/M existiert und sich deswegen auch für COM-Dateien eignet. Die COM Erweiterung hat auch ihren Ursprung in CP/M.
Beim Satz zum Large Modell:
Das Large-Modell eignet sich nur für große Anwendungen.
würde ich vorschlagen das "nur" zu entfernen. Denn man kann natürlich das Large Modell nutzen und dann trotzdem nur eine kleine Anwendung schreiben. Das ist zwar nicht besonders sinnvoll, aber möglich. Beim Huge Modell gilt das gleiche, auch da würde ich das "nur" weglassen.
Ansonsten ist auch hier beim Large Modell eine Turbo C und vermutlich auch alle C Compiler allgemein betreffende spezifische Voreinstellung bezüglich Far Zeigern angegeben, die in Assembler nicht zwingend ist. Ich selbst habe, abgesehen von ganz kleinen Sachen, zwar nie groß im Real Mode in C programmiert, aber sehr wohl in Assembler. Deswegen weiß ich jetzt nicht, wie das bei den C Compilern gehandhabt wird, wenn man Near und Far Zeiger mischen wollte. Dass Far Zeiger die Voreinstellung sind, macht natürlich Sinn und dürfte das Schreiben der Programme vereinfachen, weil man dann vermutlich aus Hochsprachensicht nicht groß darüber nachdenken muss.
Auch gibt es in Assembler meines Wissens nach keine Unterscheidung zwischen Large und Huge, das dürfte nur für die Hochsprachen relevant sein.
Ich würde daher vorschlagen, die Tabellen in ihren jeweiligen Artikeln zu belassen. Also eine eigene Tabelle für Turbo C und Microsoft C und die andere für den Segmentierung (Speicherverwaltung) Artikel. Der Grund warum ist einfach der, weil die Tabelle in Turbo C hochsprachenspezifisch ist, es ist bspw. von einer Größe von 64 KiB und 1 MiB für Code und Daten die Rede während das alles im Segmentierung (Speicherverwaltung) Artikel abstrakt als 1 Segment oder mehrere Segmente abstrahiert ist und dort nicht weiter als Größe in Bytes spezifiziert ist. Relevant ist dort nur, dass ein Segment maximal 64 KiB groß sein darf. Beides hat in seinem jeweiligen Artikel Compiler vs. abstrakter Speicherverwaltungsartikel Vorteile, diese Spezialisierung würde man aufgeben wenn man die Tabelle verschiebt. Man könnte allerdings die Spalte "Bemerkung" mit den Daten aus der Tabelle des Turbo C Artikels erweitern, da wo es Sinn macht. Das wäre zumindest meine Meinung dazu.
Die zweite Tabelle, also die Zeigertabelle im Segmentierung (Speicherverwaltung) Artikel sollte aber auf alle Fälle so bleiben wie sie ist, weil das auch ein Merk- oder Hilfsdiagramm ist, mit dem man sich gut merken kann, wann Far oder Near Zeiger in welchem Speichermodell verwendet werden. --93.229.175.119 16:11, 30. Mai 2024 (CEST)Beantworten

ANSI C Kompatibilität

[Quelltext bearbeiten]

Ab welcher Version wurde der Microsoft C Compiler 100 % kompatibel zu ANSI C und dem daraus hervorgegangenen C89 und C90 Standard? In den 80ern war das meines Wissens nach bei den meisten Compiler Herstellern noch eine Baustelle, den ANSI C Standard gab es da ja noch nicht, weswegen da jeder seine Eigenheiten hatten. Die meisten Compiler Hersteller versuchten zwar sich an das Buch The C Programming Language von Brian W. Kernighan und Dennis M. Ritchie zu orientieren, fügten aber dennoch ihre eigenen Eigenheiten und Erweiterungen dazu. Erst die 2. Auflage des Buches schaffte mehr Klarheit, wenn sie als Vorlage verwendet wurde, da erst diese weitgehend dem ANSI C Standard entspricht. --93.229.175.119 19:59, 29. Mai 2024 (CEST)Beantworten

Ab der Version 3.0 von 1985. Ich habe noch eine Tabelle darüber auf dem Computer liegen (ähnlich wie ich es bei Turbo C gemacht habe), in der das steht. Den MC-Artikel habe ich auf die schnelle mehr oder weniger in seinem alten Zustand in den ANR verschoben, weil Du es neulich bei Visual C++ erwähnt hattest; einfach damit sich hier keiner die doppelte Mühe macht. Den Artikel hab ich letztes Jahr angefangen, aber nie die Zeit / Muse gehabt, ihn fertig zu schreiben.
Ich sehe zu, dass ich das jetzt am Wochenende mache. Das kleine Code-Beispiel sollte aber auch schon ab der Version 1.0 laufen; ist ja kein Hexenwerk. --Siegbert v2 (Diskussion) 10:22, 30. Mai 2024 (CEST)Beantworten
Ja, eine Versionstabelle wäre noch super. Wenn du da schon etwas angefangen hast, dann warte ich da noch. Ich hätte ansonsten eine angelegt. Ja, das Hello World kann man so lassen. Es würde auch keinen großen Sinn machen, da ein Hello World für eine sehr alte Microsoft C Version in den Artikel einzubauen, falls diese da wesentlich von ANSI C abweichen würde. Spontan wäre mir bspw. void main anstatt int main eingefallen. COM Dateien, die aus der Zeit von CP/M stammen und daher über int 20h beendet werden (siehe auch DOS API), haben nämlich keinen Rückgabewert. Das wurde in DOS erst mit den EXE Dateien und int 21h in MS-DOS 2.0 eingeführt. --93.229.175.119 16:25, 30. Mai 2024 (CEST)Beantworten
Ich hab nochmal wegen ANSI C nachgeschaut und es war lt. dem Leibson-Artikel schon zu Lattice-Zeiten mit K&R kompatibel.
Die Info mit Version 3.0 hatte ich aus diesem Artikel: https://archive.org/details/microsoft-c-compiler-3.0-5.25.-7z
Dort ist sie aber nicht sauber belegt. Im Zweifelsfall vertraue ich dem Leibson-Artikel und hab die Aussage ganz nach oben gezogen.
Weiter unten im Entwurf (stand unter dem Tabellenentwurf) hatte ich eine Passage zur PWB-IDE angefangen, die man aber durchaus schon veröffentlichen kann. Es war/ist nicht alles; aber besser als nichts.
Wegen der COM Geschichte muss ich mal nachlesen. Der Rückgabewert 0 sollte aber eigentlich keinen Schaden anrichten, oder?
Ich muss dann auch mal langsam...heute Abend mach ich weiter. --Siegbert v2 (Diskussion) 08:00, 31. Mai 2024 (CEST)Beantworten
Ah okay. Ich denke der Leibson Artikel wird schon passen.
Der Punkt ist, COM Dateien, bzw. genauer Dateien die über int 20h beendet werden, liefern gar nichts zurück, weder 0 noch irgendeinen anderen Wert. CP/M hat das damals nicht unterstützt und MS-DOS hat das so übernommen. Das Programm wird einfach beendet, aber man kann an das Betriebssystem keinen Rückgabewert als Fehlercode zurückliefern, weswegen man da nichts zum Auswerten z.B. für Batch Dateien hat. Dass ein Rückgabewert hilfreich und sogar in Batch Prozessen sehr nützlich sein kann, hat man dann später bemerkt und erst in MS-DOS 2.0 mit den EXE Dateien und über die Interruptfunktion int 21h, wobei dann der Wert 4Ch im AH Register und der Rückgabewert im AL Register stehen muss, eingeführt. Ein Programm, dass per int 20h normal beendet wird, macht keinen Schaden, aber man weiß halt auch nicht, ob es aufgrund eines Fehlers kontrolliert beendet wurde, weil man einen Fehler OS seitig mangels Rückgabetyp nicht auswerten kann. Wollte man dem Nutzer einen Fehlercode mitteilen, dann hat man das vor beenden des Programms mit irgendeiner Textausgabe an stdout mitgeteilt. Der Text konnte alles mögliche sein, von einem "Error" bis zu einem "Fehler E3021" oder "Die Anwendung ist aufgrund eines unerwartenden Fehlers abgestürzt" wäre da alles möglich, das OS weiß davon aber nichts. Mit einer if Abfrage in bspw. einem Batch Programm könnte man damit also nichts anfangen, weil es keinen verwertbaren Returncode gibt. --93.229.175.119 18:17, 31. Mai 2024 (CEST)Beantworten
Ja da hast Du recht. Letztendlich ist das aber die Ausnahme bzw. ein einziger Fall von vielen. Bei allen anderen Speichermodellen und auch bei Tiny, wenn man es als EXE kompiliert, ist der Rückgabewert nutzbar. Ich würde daher nichts am Beispiel-Code ändern; man muss es ja nicht zwingend als Tiny/COM kompilieren, und wenn man es doch tut, passiert nichts schlimmes. Wer nicht explizit etwas an den Compiler-Einstellungen ändert, bekommt eine EXE mit Small-Modell. Den Sonderfall kann man als Satz kurz anmerken - hab ich auch schon. --Siegbert v2 (Diskussion) 09:43, 1. Jun. 2024 (CEST)Beantworten
Ja, den Beispielcode würde ich auch nicht ändern. Ich habe ja nur darauf hingewiesen, warum in manchen alten C Programmierbüchern zu DOS die main Funktion ein void als "Rückgabetyp" hat, anstatt einem int. Noch eine Anmerkung, in Assembler ist es möglich COM Dateien zu erstellen, die mit int 21h beendet werden und damit einen Rückgabewert haben. Ich würde das daher nicht an den COM Dateien festmachen, sondern an der verwendeten Interruptroutine int 21h vs. 20h für das Programmende. Bei den Hochsprachencompilern müsste man sich mal den Binärcode ansehen, um zu sehen, welche Interruptroutine diese bei COM Dateien benutzen. Nur int 20h wäre zu DOS 1.0 und gegebenenfalls CP/M kompatibel, weswegen es naheliegend ist, dass Hochsprachencompiler für COM Dateien standardmäßig dann int 20h benutzen. Und wenn der Stack bei einer COM Datei aufgeräumt wird, kommt auch int 20h zum Zug, das steht in dem von dir verlinkten Buch auf S. 518 bzw. 519. --93.229.175.119 15:14, 1. Jun. 2024 (CEST)Beantworten
Nochmal zurück zum Thema ANSI-Kompatibilität: Microsoft C war laut Microsoft C 3.0 User's Guide (Achtung 252 MB) S. 201 ff. doch erst seit Version 3.0 ANSI und K&R kompatibel. Da ist u. a. eine mehrseitige Tabelle mit allen Details aufgeführt. => Der Leibson-Artikel kann hier nicht ganz stimmen. Ein Beispiel (das jedem sofort auffällt, ohne den kompletten Standard auswendig zu kennen): Unter Lattice C und implizit auch noch bis MS C 2.0 konnten Bezeichner mit einem Dollar-Zeichen ($) beginnen. Das ist laut K&R verboten und wird erst ab Version 3.0 als Fehler angesehen. --Siegbert v2 (Diskussion) 07:15, 4. Jun. 2024 (CEST)Beantworten
Danke für den Hinweis. Der User's Guide ist recht aufschlussreich, wichtig halte ich auch den Satz in der Einleitung auf S. 201 dass die C Sprache noch in der Entwicklung sei. Das bedeutet auch, dass der MS C Compiler 3.0 sich noch an einem Entwurf von ANSI C orientiert.
Im Englischen Artikel zu Visual C wird ebenfalls erwähnt, dass erst ab Version 3.0 ANSI Kompatibilität angestrebt wurde.
Archive.org bietet übrigens eine Online Lesemöglichkeit, dann muss man nicht die ganze PDF downloaden sondern kann gezielt die Seite direkt anspringen: https://archive.org/details/microsoft-c-3.0-users-guide-and-reference-manual/Microsoft%20C%203.0%20User%27s%20Guide%20and%20Reference%20Manual/page/n201/mode/2up --93.229.175.119 10:07, 4. Jun. 2024 (CEST)Beantworten
Die ANSI Kompatibilität bezüglich Microsoft C Version 3.0 scheint nur für den Compiler zu gelten, nicht aber für die Bibliotheken. Kann es auch gar nicht, da die C89 Norm erst 1989 erschienen ist. Auch Microsoft C 5.10 ist nicht C89 kompatibel, wie ich gerade herausgefunden habe. Es fehlt zum Beispiel die Funktion strftime in time.h die es laut "C89/C90 standard (ISO/IEC 9899:1990): 4.12.3.5 The strftime function"[1] erst mit C89 gab. Die englische Wikipedia hat das auch so in ihrem Artikel "C date and time functions" stehen.
Die time.h Header Datei hat in Microsoft C 5.10 das Copyrightdatum 1985-1988 und ist damit älter als C89, was ja erst im Dezember 1989 offiziell raus kam. --84.158.120.82 22:43, 8. Aug. 2024 (CEST)Beantworten

Verwendung

[Quelltext bearbeiten]

Für den Fall, dass man im Artikel etwas zur Verwendung des MS C Compilers schreiben möchte. Der Microsoft C Compiler wurde in der Version 5.1 von der Firma Microprose für eine Vielzahl ihrer Spiele, darunter auch F-15 Strike Eagle II aus dem Jahr 1989 verwendet. Das ist in diesem Reverse Engineering Projekt belegt: https://neuviemeporte.github.io/f15-se2/2024/05/25/sausage.html MS C 5.1 erschien 1988. Das dürfte somit alle Microprose Spiele aus dieser Zeit bis sehr wahrscheinlich F-15 Strike Eagle III betreffen. Die spätere dritte Version von F-15 Strike Eagle erschien Ende 1992 und war das letzte Spiel, dass noch für den Real Mode programmiert wurde und ohne DOS Extender auskommt. Der MS Compiler war dafür somit ausreichend. Das Spiel nutzte allerdings EMS Speicher. Hier müsste man noch prüfen, ab welcher Version der MS Compiler EMS Speicher unterstützt hat. Spätere Versionen, wie bspw. F-14 Fleet Defender, erschienen 1994, nutzen DOS Extender und sind daher in 32 Bit geschrieben. Spätestens ab hier dürfte Microprose den Compiler dann gewechselt haben müssen. Da der MS Compiler nur Real Mode Programme erstellen kann, käme nur sein Nachfolger Visual C++ für Windows oder ein Compiler von einem alternativen Hersteller, eventuell Watcom C in Frage. --93.229.175.119 06:29, 4. Jun. 2024 (CEST)Beantworten

Microsoft C 2.0 basiert nicht auf Lattice

[Quelltext bearbeiten]

Das steht zumindest hier:

"Lattice C was so good that it was licensed by Microsoft and sold as Microsoft C V1.0 before being replaced by Microsoft’s own in-house Microsoft C V2.0 compiler."

https://thechipletter.substack.com/p/a-history-of-c-compilers-part-1-performance --84.140.207.90 04:45, 18. Jun. 2024 (CEST)Beantworten

Im Leibson Artikel steht das in der rechten Spalte auf Seite 84 (gedruckt; in der PDF-Datei S. 86) anders.
Abschnitt "Microsoft C 3.0":
"This compiler is not at all like the C compilers previously offered by Microsoft. Before release 3.0, Microsoft sold repackaged versions of the Lattice C compiler. With the release 3.0 package, Microsoft introduces a homegrown compiler with very powerful features that take very good advantage of MS-DOS." --Siegbert v2 (Diskussion) 11:32, 18. Jun. 2024 (CEST)Beantworten
Installiert man Microsoft C 2.0 und führt die Datei MC1.EXE (ohne Parameter) aus, bekommt man folgenden Text zu lesen:
"Microsoft C Compiler (Phase 1) V2.03
Copyright (C) 1983 by Lattice, Inc./Lifeboat Associates
File name missing"
Führt man die Datei MC2.EXE (ohne Parameter) aus, bekommt man folgenden Text zu lesen:
"Microsoft C Compiler (Phase 2) V2.03
Copyright (C) 1983 by Lattice, Inc./Lifeboat Associates
File name missing"
--Siegbert v2 (Diskussion) 11:53, 18. Jun. 2024 (CEST)Beantworten
Okay, in dem Fall würde ich mich auf die Copyrightangabe verlassen. Das hat sich damit erledigt. --84.140.207.90 16:05, 18. Jun. 2024 (CEST)Beantworten
Ich habe habe aus dem Substack-Beleg einen Weblink gemacht, da der Artikel trotz der kleinen Ungereimtheit absolut lesenswert ist. Im Abschnitt "Geschichte" habe ich bei der zu belegenden Aussage über die Version 1.x und 2.x den Leibson-Artikel aufgeführt. --Siegbert v2 (Diskussion) 07:02, 27. Jun. 2024 (CEST)Beantworten
Klingt gut. --93.229.168.100 12:10, 27. Jun. 2024 (CEST)Beantworten

Versionshistorie

[Quelltext bearbeiten]

In dem Artikel fehlt noch eine Tabelle mit Versionshistorie, wo man schnell auf einem Blick erkennen kann, wann die jeweilige Version erschienen ist und welche wichtigsten Neuerungen sie hatte. --84.158.120.82 16:29, 2. Aug. 2024 (CEST)Beantworten

  1. https://en.cppreference.com/w/c/chrono/strftime#References