Nop schrieb: > Und mal ehrlich, Wirths Schöpfungen mögen akademisch ja toll > sein, sind aber praktisch weitgehend geflopt. C nicht. Hast Du mal die Post von A.K. gelesen. Er hat doch verständlich erklärt. Ach und meinst Du Embacadero (ehemals Borland) würde immer noch Pascalcompiler bauen und zu horrenten Preisen anbieten, wenn es dafür keinen Markt gäbe? Also so ein großer Flop scheint Pascal nun auch wieder nicht zu sein. Und auch wenn Du es vielleicht nicht wahrhaben willst Pascal oder besser das was besagter Firma angeboten wird, hat sich gegenüber dem alten Pascal von Wirth erheblich weiter entwickelt. Aber eines ist auf jeden Fall geblieben : Der Compiler ist immer noch sehr restriktiv und haut einem gehörig auf Finger wenn man Mist verzapft. Nop schrieb: > Ich habe nach dem Umstieg von Pascal auf C Pascal nie mehr vermißt. Ist > wie mit ner Ex. Schön für Dich. Zeno
Ich kam Anfang der 80er zu C. Da besass ich irgendwann ein 68000 System ohne Betriebssystem und ohne Programmiersprache. Dieses System entsprach in seiner Grössenordnung ungefähr einer PDP-11 der 70er Jahre. Und da gab es einen C Compiler für 68000, den ein anderer Studi als Diplomarbeit aus einem C Compiler für PDP-11 und andere Zielsysteme gestrickt hatte, und der lief auf einer VAX von der Uni. Quellcode war verfügbar, Zugang zur VAX auch. Das Ergebnis war ein einfaches Betriebssystem für das 68000 System und ein daran adaptierter Compiler, Assembler, Linker. Zusammen mit einem Freund entwickelt. Das ist ein für damalige Verhältnisse durchaus typischer Werdegang. Man nimmt was man hat und lässt sich von dem inspirieren, was man kennt. In dieser Dimension war C völlig passend. Kein Internet, nicht einmal Usenet. Der Compiler startete von Floppy-Disk und war schnell. Irgendwann kam dann Ada, weil dem DOD der Software-Wildwuchs auf die Nerven ging. Die Sprache adressierte erkennbar genau diesen mir wohlbekannten Bereich, von lowlevel I/O bis Betriebssystem und dessen Grundanwendungen. Es gab damals aber einen entscheidenden Unterschied: Die ersten Ada Compiler waren wahre Monster und nicht praktisch einsetzbar. Das "Plonk" konnte man regelrecht hören, das ging nicht nur mir so. C war und blieb praktischer.
@Zeno Bitte stapel mal ein bisschen tiefer, für das, dass du sowas ablässt: Zeno schrieb: > Ach ja: Diese -> Schreibweise ist auch wieder so ein C++ Krampf der sich > erst mal einem erschließen muß. Bei C# nimmt man übrigens wieder einen . > für so was, wie in anderen Programmiersprachen auch. reißt du jetzt ganz schön die Klappe auf. Kannst du wirklich C? Weil die Aussage ist ziemlich, sagen wir mal, kurios...
Rolf M. schrieb: > Du weißt aber, dass sich im Bezug auf die Nutzung von if durch die > Einführung von bool in C++ genau gar nichts geändert hat? Das weis ich schon. C++ ist an vielen Stellen halt immer noch C. Man hat halt Objekte hinzugefügt, Strings eingeführt und einiges mehr, aber man hat es versäumt, das was mangelhaft ist ohne wenn und aber rauszuschmeißen. Und man kann dies weiter zu C# spinnen. Auch da hat man wieder viel Neues eingeführt, darunter auch viele Sachen die einem das Leben leichter machen. Aber bei einigen neuen Sachen ist man auch wieder nicht konsequent gewesen und hat es von Anfang bis Ende ordentlich "durchgestylt". Ergebnis dieses Flickwerkes ist es natürlich, das man wieder erst mal in diverse Sackgassen rennt. Und ja es ist im Grundkern immer noch C obwohl es hier hätte konsequent rausschmeißen können. Die Hardwarenähe die mir C bietet werde ich in C# wohl eher nicht brauchen, denn keiner wird damit z.B. ein Programm für einen µC schreiben. Zeno
Manche Kritik hier leidet ein wenig am Ansatz. Denn es ist sinnlos, sich an Trivialitäten wie for(;;) und while(1) aufzuhängen. Das ist einfach nur Kinderkram. Ob man das nun elegant findet oder nicht, wer darüber länger als 1min stolpert hat ein anderes Problem. Längere Streiterei darüber führt deshalb allzu leicht zur Einschätzung "der spinnt doch". Und wenn man diesen Ruf mal weg hat ... NB: Eine Sprache zu verwenden heisst nicht, sie auch wirklich gut zu finden. Und irgendwann wird es zur Gewohnheit. The devil you know.
:
Bearbeitet durch User
Zeno schrieb: > Und man kann dies weiter zu C# spinnen. Auch da hat man wieder viel > Neues eingeführt, darunter auch viele Sachen die einem das Leben > leichter machen. Aber bei einigen neuen Sachen ist man auch wieder nicht > konsequent gewesen und hat es von Anfang bis Ende ordentlich > "durchgestylt". Ergebnis dieses Flickwerkes ist es natürlich, das man > wieder erst mal in diverse Sackgassen rennt. Und ja es ist im Grundkern > immer noch C obwohl es hier hätte konsequent rausschmeißen können. Die > Hardwarenähe die mir C bietet werde ich in C# wohl eher nicht brauchen, > denn keiner wird damit z.B. ein Programm für einen µC schreiben. Erzähl mal mehr darüber. C# hat nämlich außer der Syntax sehr wenig mit C gemein (dafür mit Java). C# hat eigentlich gar keine "Hardwarenähe", dass es Zeiger gibt, wissen die Wenigsten, weils auch praktisch keiner braucht (außer im Zusammenspiel mit nativen Code). Die gibts nur im unsafe Block und die Zeigerarithmetik ist extrem eingeschränkt.
Christopher C. schrieb: > C# hat eigentlich gar keine "Hardwarenähe", > dass es Zeiger gibt, wissen die Wenigsten, weils auch praktisch keiner > braucht (außer im Zusammenspiel mit nativen Code). Zeiger? Die könnten beim Schreiben eines Uhrenprogrammes nützlich sein. O.T. Eigentlich gehört doch hier ein Zaun drum mit Warnschildern: "Achtung! C-Fetischisten Nicht füttern oder tränken! Insassen werfen mit Operatoren um sich!" MfG Paul
:
Bearbeitet durch User
W.S. schrieb: > Die Gründe für C sehe ich zu 99% im außertechnischen Bereich. Die > Schwierigkeit, mit C zurecht zu kommen, ist gewollt und dein "mögen" hat > einen Geschmack nach "endlich bin auch ich elitär" - ich weiß, sowas > steckt in jedem Manne mental drin. Nö, sondern weil mich bei Pascal nach der Anfangszeit die Restriktivität der Sprache zunehmend genervt hat. Die ist gut für Leute, die nicht wissen, was sie tun und deswegen die Grenzen unabsichtlich und irrtümlich überschreiten. Deswegen ist es eine gute Lehrsprache. Jenseits davon wird diese Philosophie zum Ärgernis. Ich möchte nicht dauernd den Compiler bekämpfen müssen, sondern ich will, daß der Compiler das umsetzt, was ich sage, Punkt. C gibt mir genau diese Grundeinstellung. > Aber ich guck nach vorn, und da sehe ich kein Vorwärtskommen für C - im > Gegensatz zu Pascal. Guck dir doch mal beides zum Vergleich an: der > erste und wohl letzte Markstein bei C war ANSI Falsch, C99 beispielsweise hat auch portable Datentypen eingeführt. Gut, Du hast ja schon vorgeführt, daß Du nicht siehst, was eigentlich der Punkt an uint32_t ist. Über die fast-Datentypen muß man dann wohl nicht mehr reden. > Und nun guck dir Pascal in seiner heutigen Form (FPC oder Embarcadero) > an. Merkst du da was? Ja, besonders bei Embarcadero merke ich, daß ich mich nie auf eine proprietäre Sprache verlassen würde, die unter der Fuchtel einer Firma steht. Besonders dann nicht, wenn es dieser Firma nicht besonders gut geht. Daß der spanische Entwicklungsstandort mit 80 Leuten dichtgemacht wurde dieses Jahr, weißt Du so gut wie ich. > Pascal ist zukunftsfähig, C nicht. Pascal hat seine Zukunft bereits hinter sich. > Oder anders herum: Du magst C mehr als Pascal, aber kann C deshalb > Objektorientiertheit? In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze. Exceptions brauche ich nicht, weil ich von vornherein Fehlerfälle nicht zulasse. Sowas läuft bei mir unter vernünftigem Design, daß man das abfängt. Strings gehen in C als C-Strings tadellos. Man kann sogar Pascalstrings nachbilden, falls man das wollen sollte. Natürlich gibt die Sprache das her. Nur, insofern gebe ich Dir recht, ich würde in C nicht GUIs programmieren wollen. Ich habe das nämlich getan und WEISS, wie das ist - echt nicht schön. Massiv parallele Architekturen wären auch kein Anwendungsfall für C, und auch nicht für C++, und auch nicht für OOP generell. C ist als lowlevel-Sprache positioniert, für Systemprogrammierung, und dafür ist dieser portable Makroassembler einfach super, IMO.
W.S. schrieb: > Formal hast du Recht, aber es ist einer der vielen Geburtsfehler von C > und hätte schon seit langem ausgemerzt gehört. Weißt du, wenn die Leute hätten für alles überall vorzugsweise Pascal nehmen wollen, dann wäre die Sprache ja da gewesen. Sie ist einigermaßen genauso alt wie C, beide standen durchaus in einer gewissen Konkurrenz. Wenn nun 40 Jahre später Pascal eher ein Rand-Dasein führt, dann kannst du natürlich vortrefflich auf C herumhacken, was man dort hätte alles anders und besser machen sollen (bis es am Ende auch nur ein anderes Pascal wäre). Trotzdem macht die Welt eben in erster Linie C, und nein, das liegt nicht nur an der Verfügbarkeit von Compilern. Pascal-Compiler gab's auch schon lange, auch günstig (wie Turbo-Pascal) oder kostenlos (GNU). Es muss also irgendwas anderes sein, warum es eben doch das ach so schröckliche, mit Geburtsfehlern noch und nöcher versehene C ist, was heutzutage allgegenwärtig ist. Ich habe übrigens auch viel in Pascal programmiert und fand das keineswegs schlecht.
Paul B. schrieb: > Zeiger? Die könnten beim Schreiben eines Uhrenprogrammes nützlich sein. > > O.T. > > Eigentlich gehört doch hier ein Zaun drum mit Warnschildern: > > "Achtung! C-Fetischisten > > Nicht füttern oder tränken! > > Insassen werfen mit Operatoren um sich!" Geiler Post! ER hat nicht ganz unrecht.
Paul B. schrieb: > "Achtung! C-Fetischisten Bisschen sehr bemüht, der Witz. Es geht hier in den besseren Teilen auch darum, über C oder Sprachen generell zu diskutieren, gerade ohne sich gegenseitig Fetischismus oder Fanatismus vorzuwerfen, bloss weil man sie kennt und nutzt. Und umgekehrt auch darum, nicht jene in Bausch und Bogen zu verdammen, bloss weil sie sie kritisieren. Der Vorwurf von Fetischismus erhöht nur die Aggression.
Nop schrieb: > In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams > nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende > Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze. Du hast den Sinn von OOP nicht verstanden. Nop schrieb: > Exceptions brauche ich nicht, weil ich von vornherein Fehlerfälle nicht > zulasse. Sowas läuft bei mir unter vernünftigem Design, daß man das > abfängt. So viel Überheblichkeit muß man erst mal drauf haben. Da würde sogar der Schöpfer von C erblassen Zeno
In einem der K&R Bücher schreiben die Autoren selbst, dass sie mit dem langfristigen Erfolg der Sprache gar nicht gerechnet hatten. Bei der Entwicklung hatten sie nicht darüber nachgedacht, welche Bedürfnisse die Programmierer 40 Jahre später haben würden - auf Maschinen, die 10000 mal so Leistungsstark wären. Damals hatte man über Internet, Video-Player, 3D Kriegsspiele und Virtual Reality verständlicherweise noch nicht so viel nachgedacht.
Zeno schrieb: > Nop schrieb: >> Und mal ehrlich, Wirths Schöpfungen mögen akademisch ja toll >> sein, sind aber praktisch weitgehend geflopt. C nicht. [...] > Ach und meinst Du Embacadero (ehemals Borland) würde immer noch > Pascalcompiler bauen und zu horrenten Preisen anbieten, wenn es dafür > keinen Markt gäbe? Borland Pascal verhält sich zu Wirths Pascal ungefähr so wie C++ zu C. Mit der Wirthschen Urversion ließ sich wirklich nur akademischer Kram verbrechen, für die praktische Nutzung waren die diversen Erweiterungen von Turbo Pascal einfach notwendig (jedenfalls wenn man mehr als Batchverarbeitung oder Interaktion a la dumb TTY machen wollte).
Zeno schrieb: > Du hast den Sinn von OOP nicht verstanden. Nein, ich habe nur hinter den OOP-Hype der 90er gesehen, als OOP als silver bullet für alles inklusive Fußpilz angepriesen wurde. > So viel Überheblichkeit muß man erst mal drauf haben. Wenn Du Deine System nicht robust designen willst, ist das ja nun nicht mein Problem. Tatsächlich ist das Berücksichtigen von Fehlerfällen und Randfällen 90% von robustem Systemdesign.
Nop schrieb: > Wenn Du Deine System nicht robust designen willst, ist das ja nun nicht > mein Problem. Tatsächlich ist das Berücksichtigen von Fehlerfällen und > Randfällen 90% von robustem Systemdesign. Natürlich möchte jeder, daß seine Software stabil läuft und genau aus diesem Grund wird Software so geschrieben, daß möglichst alle Fehler abgefangen werden. Ich kann aber nicht alle Fehler im voraus erfassen. Beispiel: Ich möchte mit meinem Programm Messwerte einlesen und diese weiter verarbeiten. Dabei wird mit diesen Werten gerechnet und u.a. auch eine Division durch geführt. Dumm bloß wenn dabei ein Wert zufällig 0 ist oder noch blööder bei der Berechnung ergibt sich ein Wert der 0 ist und mit dem muß weiter gerechnet werden. Man könnte das z.B. mit if abfangen und so die Berechnung bei 0 überspringen. Wenig elegant! Ich kapsle die Berechnung, bei Pascal, in einem try except oder auch try finally Block, je nachdem was ich erreichen möchte. Ich kann so auf solche Fehler reagieren. In diesem Sinne sind Exceptions ein Segen. Sie sind schlichtweg eine Hilfe, aber sie dienen definitiv nicht dazu schlampig zu programmieren. Exceptions machen durchaus Sinn und können das Leben erheblich vereinfachen. Gerade wenn man Programme mit viel Userinteraktion schreibt kommt man fasst nicht mehr an Exceptions vorbei um zu verhindern, daß das Programm durch Fehleingaben ständig abstürzt, es sei denn man möchte die Schmerzgrenze der User austesten. Zeno Zeno
Exceptions können auch die Les- und Wartbarkeit von Programmen verbessern. Wenn auf jede produktive Zeile 20 Zeilen Fehlerbehandlung kommen, dann sieht man den Wald vor lauter Bäumen nicht mehr.
Zeno schrieb: > Ich kann aber nicht alle Fehler im voraus erfassen. Das ist die Kunst im Systemdesign. Ich habe zeitweise die Entwicklung bewußt für einige Jahre verlassen und stattdessen im Testfeld gearbeitet. Die Rechtfertigung, wieso die jeweilige Firma einen für sowas überhaupt bezahlt, ist die, daß man Fehler findet, bevor der Kunde auf sie trifft und mault. Das gibt einem definitiv eine völlig andere Denkweise. Entwickler wollen, daß ihr System funktioniert. Tester wollen zeigen, daß es das nicht tut. Rate mal, wie sich solche Erfahrung dann aufs Systemdesign auswirkt. > Beispiel: > Ich möchte mit meinem Programm Messwerte einlesen und diese weiter > verarbeiten. Dabei wird mit diesen Werten gerechnet und u.a. auch eine > Division durch geführt. Also komm, wenn ein Algorithmus Divisionen mit Meßwerten macht, dann ist es vollkommen offensichtlich, daß man sich Gedanken machen muß, was bei null herauskommt - und sei es, daß die Null durch einen Kabelbruch zustandekommt, dessentwegen irgendein Pulldown die Spannung auf GND zieht. > Man könnte das z.B. mit if abfangen > und so die Berechnung bei 0 überspringen. Wenig elegant! Ich kapsle die > Berechnung, bei Pascal, in einem try except oder auch try finally Block, > je nachdem was ich erreichen möchte. Siehste, und ich mache mir Gedanken, wieso da eine Null ist, wo keine sein dürfte - und erwäge irgendeine Art von hilfreicher Fehlernachricht, weil offenbar irgendwas mit dem System nicht stimmt. Statt eine Exception vorzuschieben, sehe ich validity-Bits für die Ausgangsdaten vor. > Gerade wenn man Programme mit viel Userinteraktion > schreibt kommt man fasst nicht mehr an Exceptions vorbei um zu > verhindern, daß das Programm durch Fehleingaben ständig abstürzt Ja, wenn man schlampig programmiert und die Eingabedaten nicht validiert, dann schon. Ich rechne beim Systemdesign allerdings von vornherein damit, daß das System von allen Seiten mit ungültigen Daten aller Art bombardiert wird, und erwäge, welche Teile des Systems dann eigentlich noch funktional sein können und welche nicht. Dadurch erreiche ich, daß die Dinge, die dennoch funktionieren sollten, das auch tun. Ich designe auch Module so, daß sie sich selbst prüfen, selbst wenn ich weiß, daß diese Checks aufgrund des Gesamtdesigns nie zuschlagen dürften. Aber halt rein, falls sich später mal das Interfacing ändern sollte. Weil ich meine Denkarbeit nicht an Compiler abgebe. Deswegen funktionieren meine Systeme auch unter ungünstigen Umständen noch soweit, wie es systembedingt eben möglich ist. Mit Fallbackmodi aller Art. Ich habe derlei nicht programmiert, aber vielleicht ist Dir der Qantas-Unfall eines A380 ein Begriff. Bei dem Flug ist ein Triebwerk explodiert, und die Trümmerteile haben diverse Energieleitungen, Datenleitungen und Hydraulikleitungen des Flugzeugs zerrissen. Das war Qantas Flight 32, wenn Du googeln möchtest. Das Wunder ist, daß die Kiste zwar vollkommen in den Seilen hing, hunderte von Fehlermeldungen, und außer den guten Entwicklern war es auch der brillante Kapitän. Aber Tatsache ist, der Flieger ist selbst dermaßen angeschlagen heil runtergekommen OHNE Personenschäden. DAS nenne ich ein Systemdesign. Selbst wenn man nicht so kritische Systeme programmiert, aber SOWAS sind meine Vorbilder.
Nop schrieb: > DAS nenne ich ein Systemdesign. ... und eine grosse Portion Glück. Das Systemdesign war beispielsweise in einem Punkt so bescheiden, dass der Vogel wohl wegen Spritmangel runtergefallen wäre bevor sie die letzte der Meldungen lesen konnten, wenn es einen Tank erwischt hätte. Haben sie daraufhin geändert, damit die Piloten in solchen Fällen nicht in Meldungen ersaufen.
:
Bearbeitet durch User
A. K. schrieb: > der Vogel wohl wegen Spritmangel runtergefallen wäre Das wäre er nicht, denn außer bei Start und Landung kann so ein Flieger selbst völlig ohne Sprit noch hunderte Kilometer segeln. Für die Elektronik klappt dann eine Windturbine aus, die aus dem Fahrtwind Strom erzeugt. Im Übrigen war eines der Hauptprobleme dabei, daß der Flieger wesentlich ZUVIEL Sprit hatte, weswegen der noch stundenlang erstmal rumgeflogen ist, um ausreichend Sprint zu verbrennen, so daß die Landung möglich wurde.
A. K. schrieb im Beitrag #4758902: > Aber das geht nun etwas vom Thema weg. Wenn man mal davon absieht, dass > es nie möglich sein wird, alle Eventualitäten vorher einzurechnen. Naja, aber Fakt ist, das hat funktioniert, was ich schon echt bemerkenswert finde. Die meisten von uns hier werden nie dermaßen anspruchsvolle Systeme entwerfen, aber ein Vorbild ist sowas dennoch. Nur, wenn ich schon lese, daß man Exceptions deswegen "braucht", weil man zu faul ist, Eingabedaten zu validieren, dann krieg ich doch nen Föhn. Das System wird auch mit Exceptions ein ziemlicher Mott werden.
Nop schrieb: > Nur, wenn ich schon lese, daß man Exceptions deswegen "braucht", weil > man zu faul ist, Eingabedaten zu validieren, dann krieg ich doch nen > Föhn. Das System wird auch mit Exceptions ein ziemlicher Mott werden. Yep. Das muss in die Hose gehen. Wird eher a posteriori interessant. Also beispielsweise ob du jeden verdammten Aufruf von irgendwas einzeln auf alle Fehlerwerte abklapperst und behandelst, oder ob das summarisch im Exception-Teil endet.
A. K. schrieb: > Also beispielsweise ob du jeden verdammten Aufruf von irgendwas einzeln > auf alle Fehlerwerte abklapperst und behandelst, oder ob das summarisch > im Exception-Teil endet. Ja, und ein System, das am Ende nur weiß "irgendwas ist verkehrt", kann darauf dann auch nicht mehr differenziert reagieren. Das wäre ja noch irgendwo tolerierbar als allerletzter Fallback-Fall, aber offensichtlich verführt eine Programmiersprache mit solchen Features dann stattdessen zu schlampiger Fehlerbehandlung. Einfacher zu programmieren, weil man nicht nachdenken braucht, aber das Ergebnis ist eben schlechter. Wenn ich solche schlampigen Ergebnisse aber weder will noch brauche, dann brauche ich auch keine Sprache mit solchen Features.
W.S. schrieb: > es kann alles, was C kann Seit wann kennt Pascal variadische Funktionen? Das wäre ja mal was neues.
Nop schrieb: > Ja, und ein System, das am Ende nur weiß "irgendwas ist verkehrt", kann > darauf dann auch nicht mehr differenziert reagieren. Exceptions bedeuten nicht, dass jede Information über deren Ursache verloren ginge. Und es geht dabei auch nicht um /0 oder Index-Overflow, sondern bietet eine Alternative zu beispielsweise durch Layer durchgereichten Error-Returns. Das ist natürlich kein Allheilmittel für alle Lebenslagen und kann seinerseits auch wiederum irritieren. Fehlerbehandlung in klassischer Prozeduraler Programmierung kann den produktiven Code mittendrin ziemlich verwässern, so dass man ihn kaum noch wiederfindet. Exception-Handling kann das aufdröseln, indem der produktive Code relativ dicht steht und damit am Stück verständlich wird, während die Fehlerhandhabung ebenso konzentriert an anderer Stelle steht.
:
Bearbeitet durch User
Nop schrieb: > Nur, wenn ich schon lese, daß man Exceptions deswegen "braucht", weil > man zu faul ist, Eingabedaten zu validieren, dann krieg ich doch nen > Föhn. Du hast möglicherweise nicht ganz verstanden, was Exceptions sind und wie sie eingesetzt werden. Sie ersetzen keineswegs die Prüfung von Eingabedaten, sondern stellen einen Mechanismus bereit, die durch die Prüfung erkannten Fehlerfälle auf unkomplizierte Weise an den Programmteil zu transferieren, der die Reaktion darauf implementiert. Wenn bspw. auf hardwarenaher Ebene bei der Abfrage UART-Statusregisters festgestellt wird, dass ein Byte fehlerhaft übertragen worden ist, muss dieser Fehlerstatus oft über viele Unterprogrammebenen an das Hauptprogramm oder ein in der Hierarchie höherliegendes Unterprogramm hochgereicht werden, das seinerseits eine andere Routine aufruft, die eine entsrpechende Aktion ausführt (im einfachsten Fall bspw. eine Fehlermeldung auf dem Bildschirm ausgibt). Der klassische Weg verwendet dabei Fehlercodes, die als Funktionswert der jeweiligen Unterprogramme an die jeweils nächsthöhere Ebene zurückgegeben werden. Diese Methode hat aber den Nachteil, dass jedes dieser Unterprogramme abfragen muss, ob der Aufruf des jeweils nächsttieferen Unterprogramms erfolgreich verlief. Man braucht also nicht nur eine Fehlerabfrage an der eigentlichen Fehlerquelle, sondern ganz viele (jeweils eine pro Unterprogrammebene). Mit Exceptions reduziert sich der ganze Aufwand auf die eigentliche Abfrage des UART-Registers, das Auslösen der Exception bei erkanntem Fehler und das Abfangen des Fehlers auf der Unterprogrammebene, wo auch die Reaktion auf den Fehler ausgelöst wird. Alle Unterprogramme, die in der Hierarchie dazwischen liegen, bleiben von der Fehlerbehandlung völlig unberührt. Fehlerbehandlungscode gibt es also nur dort, wo der Fehler entsteht und dort, wo er behandelt wird, sonst nirgends. Das erhöht die Übersicht und die Erweiterbarkeit des Programms beträchtlich.
Rufus Τ. F. schrieb: > Seit wann kennt Pascal variadische Funktionen? Das wäre ja mal was > neues. Ich denke, das war eher im Gesamtbild gemeint. Nicht bezogen auf zeilenweise identische Umsetzung. Braucht man das unbedingt?
Nop schrieb: > Siehste, und ich mache mir Gedanken, wieso da eine Null ist, wo keine > sein dürfte - und erwäge irgendeine Art von hilfreicher Fehlernachricht, > weil offenbar irgendwas mit dem System nicht stimmt. Statt eine > Exception vorzuschieben, sehe ich validity-Bits für die Ausgangsdaten > vor. Oh da sieht man das Du von der Praxis halt weit entfernt bist. Messwerte mit Null sind durchaus möglich und auch kein Fehler. Wenn ich zum Beispiel eine Messmaschine kalibriere, dann nehme ich Längennormal und messe dieses mehrmals mit der Maschine aus. Dabei interessiert mich nicht die absolut gemessene Länge, sondern für mich ist die Differenz zwischen dem Nominalwert (also der kalibrierten Länge des Normals) und dem Messwert interessant und diese kann durchaus auch Null sein. Mit diesen Werten werden jetzt diverse Berechnungen durchgeführt und da ist es schon möglich das mathematisch nicht definierte Berechnungen daraus resultieren, wie z.B. Divisionen durch Null. Die Messwerte werden automatisch erzeugt und auch die Auswertung läuft weitestgehend automatisch ab. Da kann ich nicht darauf vertrauen das da nur korrekte Werte vorkommen. Für diesen Anwendungsfall sind Exceptions ein Segen. Als ich die Vorgängersoftware programmiert habe gab es noch kein Exceptionhandling und man mußte selbst dafür sorgen so was abzufangen, was in aller Regel nicht zu 100% gelingt. Selbst wenn man die heute verfügbare Unittest bemühen würde kann man nicht alle Fehler voraussehen, denn auch der Unittest muß man sagen was sie prüfen soll. Erkennt man eine Konstellation nicht dann wird dieser Fall auch nicht abgeprüft. Ich (muß) arbeite mit einem Kollegen zusammen der genauso wie Du meint das Programmieren erfunden zu haben. Er läßt sich nichts sagen und meint alles im Griff zu haben. Er versucht sich seit 2 Jahren daran mein Programm nachzuprogrammieren - bisher mit mäßigen Erfolg. Unittest ist erfolgreich durchgelaufen, aber leider sind die Testfälle als auch das aktuelle Programm soweit an der Realität vorbei, daß an einen produktiven Einsatz noch lange nicht zu denken ist. Du glaubst ernsthaft, daß Du unfehlbar bist? Träum weiter. Zeno
A. K. schrieb: > Fehlerbehandlung in klassischer Prozeduraler Programmierung kann den > produktiven Code mittendrin ziemlich verwässern Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus".
Yalu X. schrieb: > Man braucht also > nicht nur eine Fehlerabfrage an der eigentlichen Fehlerquelle, sondern > ganz viele (jeweils eine pro Unterprogrammebene). Das aber auch nur dann, wenn der Sinn der ganzen Aktion letztlich der ist, die Entscheidung an den Nutzer abzuwälzen. Auf Microcontroller-Systemen GIBT es aber keinen "Nutzer", fertig. Das System muß selber zusehen, wie es mit der Situation klarkommt. Es hängt irgendwo da draußen, ist auf sich gestellt, und niemand wird kommen, um es zu betüddeln und irgendwas zu "klicken". Von daher halte ich den ganzen Ansatz schon für verkehrt. Die unterste Schicht soll dann eben den Fehler feststellen und schlicht dafür sorgen, daß auf höherer Ebene ein Protokollfehler entsteht, der dann letztlich zu einem Re-Transmit führt. Ooops.. dazu müssen die Pakete/Nachrichten/whatever auch Checksummen haben? NEIN! DOCH! OHHH! (;
Nop schrieb: > Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare > Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus". Egal wie oft du Inputs validierst: Ob es das Item überhaupt gibt, dessen Kennzeichnung übergeben wird, weisst du erst, wenn du danach fragst. Ist ein Fehlschlag selten und unerwartet, dann kann es wesentlich übersichtlicher sein, auf einem recht hohen Layer damit umzugehen, als den Erfolg in allen Layern zwischendrin jedesmal abzufragen.
:
Bearbeitet durch User
Zeno schrieb: > Oh da sieht man das Du von der Praxis halt weit entfernt bist. Im Gegenteil, offensichtlich habe ich davon wesentlich mehr als Du. > Messwerte > mit Null sind durchaus möglich und auch kein Fehler. Wenn es ein Meßwert ist, durch den per Design zu dividieren ist, dann IST ein Meßwert null ein Fehlerzustand. Wenn Du das anders siehst, wirf mir nicht fehlende Praxis dafür vor. > Beispiel eine Messmaschine kalibriere, dann nehme ich Längennormal und > messe dieses mehrmals mit der Maschine aus. Dabei interessiert mich > nicht die absolut gemessene Länge, sondern für mich ist die Differenz > zwischen dem Nominalwert (also der kalibrierten Länge des Normals) und > dem Messwert interessant und diese kann durchaus auch Null sein. Ach. Jetzt erklär mir nur noch, in welchem Falle Du dann durch diese Differenz zu dividieren gedenkst - wo bei so einem Design es gerade der Idealzustand ist, daß die Differenz null ist! > Mit > diesen Werten werden jetzt diverse Berechnungen durchgeführt und da ist > es schon möglich das mathematisch nicht definierte Berechnungen daraus > resultieren, wie z.B. Divisionen durch Null. Das ist nicht möglich, sondern das ist grobe Schlamperei. > Für diesen Anwendungsfall sind Exceptions ein Segen. Sage ich ja. Du delegierst die Konsequenzen Deiner Schlamperei an die Programmiersprache und wunderst Dich, wieso ich derlei nicht brauche. Vielleicht, weil ich etwas mehr Praxis habe und mir deswegen gerade die Gedanken mache, die Du lieber verweigerst und an den Compiler delegierst. > Du glaubst ernsthaft, daß Du unfehlbar bist? Wenn ich einen mathematischen Algorithmus habe, dann bin ich auch in der Lage, den Gültigkeitsbereich der Parameter zu bestimmen. Dafür hatte ich einige Semester Mathe an der Uni. Sollte der mathematische Algorithmus so komplex sein, daß ich dazu nicht in der Lage bin, dann ist meine Konsequenz nicht, meine Inkompetenz an den Compiler zu delegieren, sondern dann frage ich einen Mathematiker. Dafür gibt es solche Leute. Ich bin jedenfalls gut genug in Mathe, um zu begreifen, ab wo ich den Überblick verliere, und ich weiß auch, was dann zu tun ist. Nicht rumpfuschen, sondern Experten befragen.
A. K. schrieb: > Exceptions bedeuten nicht, dass jede Information über deren Ursache > verloren ginge. Und es geht dabei auch nicht um /0 oder Index-Overflow, Bei einer Exception geht auch nichts verloren, da hast Du völlig recht. Man bei der Behandlung der Exception schon abfragen warum diese aufgetreten ist. Aber man kann z.B. auch, um mal bei meinem Beispiel zu bleiben, einen Defaultwert setzen wenn die Berechnung schief geht, oder den Messwert von einer weiteren Verarbeitung ausschließen. Es kommt halt immer darauf an was man bezwecken möchte. Eine allgemeingültige Empfehlung kann es da nicht geben. Ja und es ist auch eine gute Sache, daß man Exceptions durchreichen und an zentraler Stelle verarbeiten kann. Yalu X. schrieb: > Du hast möglicherweise nicht ganz verstanden, was Exceptions sind und > wie sie eingesetzt werden. Ich denke mal Du hast es erfasst. Aber er programmiert mit C und da gibt es keine Exceptions, also muß er das Fehlen selbiger schön reden. Zeno
A. K. schrieb: (Variadische Funktionen) > Braucht man das unbedingt? Selbst Pascal braucht sie (write[ln], read[ln]).
Nop schrieb: > A. K. schrieb: >> Fehlerbehandlung in klassischer Prozeduraler Programmierung kann den >> produktiven Code mittendrin ziemlich verwässern > > Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare > Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus". @A.K. Du solltest NOP huldigen - er ist gottgleich und Du wirst ihn nicht von den Vorteilen eines überlegt eingesetzten Exceptionhandlings überzeugen können. Er kann es auch gar nicht richtig einschätzen, da er in seiner C-Welt lebt und unfähig ist über den Tellerrand zu schauen. Er setzt Exceptions und deren Handling mit Faulheit gleich und erkennt nicht das selbiges richtig eingesetzt ein mächtiges Werkzeug ist. Er hängt bei K&R fest und hat einfach verpasst, daß sich die Programmierwelt weiter entwickelt hat und alle modernen Programmiersprachen Exceptions unterstützen. Selbst bei den alten Programmiersprachen, wie z.B. auch Pascal, hat man die Mächtigkeit von Exceptions erkannt und diese in den Sprachumfang aufgenommen W.S. hat es schon richtig erkannt als er in seinem Post schrieb : W.S. schrieb: > Ja, C ist tatsächlich veraltet ... Zeno
Jörg W. schrieb: > (Variadische Funktionen) > >> Braucht man das unbedingt? > > Selbst Pascal braucht sie (write[ln], read[ln]). Modula nicht mehr. Wirth war lernfähig.
Zeno schrieb: > Er kann es auch gar nicht richtig einschätzen, da er in seiner > C-Welt lebt und unfähig ist über den Tellerrand zu schauen. Das verstehst Du falsch. Ein vernünftiges Design hat nichts mit einer Programmiersprache zu tun. Es ist nur so, daß Du versuchst, Deine Designschwächen mit Programmiersprachen zu kaschieren, weswegen Du solche brauchst, die das unterstützen. Ich brauche das nicht und vermisse das daher auch nicht.
A. K. schrieb: >> Selbst Pascal braucht sie (write[ln], read[ln]). > > Modula nicht mehr. Wirth war lernfähig. Allerdings mit einem Rückschritt in der Benutzerfreundlichkeit.
1 | WriteString("foo bar ist "); |
2 | WriteInt(foobar, 2); |
3 | WriteString(" Äppelstücken"); |
4 | WriteLn; |
vs.
1 | WriteLn('foo bar ist ', foobar, ' Äppelstücken'); |
(vs.
1 | printf("foo bar ist %d Äppelstücken\n", foobar); |
:)
Jörg W. schrieb: > Selbst Pascal braucht sie (write[ln], read[ln]). Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in Pascal selbst geschrieben?
.. und nebenbei bemerkt, von jemandem, der im Thread bewiesen hat, daß er von C gar keine Ahnung hat, einen C-Tellerrand vorgeworfen zu bekommen, ist schon drollig. Bilde Du Dich erstmal soweit fort, daß Du diesen Tellerrand erreichst, dann reden wir weiter.
Nop schrieb: > Yalu X. schrieb: >> Man braucht also >> nicht nur eine Fehlerabfrage an der eigentlichen Fehlerquelle, sondern >> ganz viele (jeweils eine pro Unterprogrammebene). > > Das aber auch nur dann, wenn der Sinn der ganzen Aktion letztlich der > ist, die Entscheidung an den Nutzer abzuwälzen. Auf > Microcontroller-Systemen GIBT es aber keinen "Nutzer", fertig. Das mit der Fehlermeldung auf dem Bildschirm war nur ein Beispiel: Yalu X. schrieb: > Wenn bspw. auf hardwarenaher Ebene bei der Abfrage UART-Statusregisters > festgestellt wird, dass ein Byte fehlerhaft übertragen worden ist, muss > dieser Fehlerstatus oft über viele Unterprogrammebenen an das > Hauptprogramm oder ein in der Hierarchie höherliegendes Unterprogramm > hochgereicht werden, das seinerseits eine andere Routine aufruft, die > eine entsrpechende Aktion ausführt (im einfachsten Fall bspw. eine > Fehlermeldung auf dem Bildschirm ausgibt). Ersetze den Text in der Klammer einfach durch eine beliebige andere Fehlerbehandlungsmethode, die dir einfällt. Ich wollte mit dem obigen Satz nur ausdrücken, dass die Fehlerbehandlung i.Allg. nicht im selben Unterprogramm stattfindet, in dem der Fehler erkannt wird, sondern in einer darüberliegenden Hierarchieebene. Und dafür erweisen sich Exceptions als sehr praktisch.
Yalu X. schrieb: > Ich wollte mit dem obigen Satz nur ausdrücken, dass die Fehlerbehandlung > i.Allg. nicht im selben Unterprogramm stattfindet, in dem der Fehler > erkannt wird, sondern in einer darüberliegenden Hierarchieebene. Ja, das ergibt Sinn. Nur, für einen Uart-Fehler würde ich das schlichtweg in einen Protokoll-Fehler rasseln lassen, den man ohnehin braucht, wenn der Fehler schon auf dem Draht passiert sein sollte. Dagegen muß man sich ohnehin absichern. Dadurch braucht man für solche Protokoll-Sachen nicht haufenweise Errorcodes nach oben durchreichen. Das Ergebnis wird dann schlichtweg ein Re-ransmit werden, wenn die Statemachine da oben arbeitet, wie sie soll. Ich habe jahrelang mit solchen Problemen in der Datenkommunikation gearbeitet und nie Exceptions gebraucht. Weil die Protokolle vernünftig designed waren, halt auf Übertragungsfehler aller Art. Verdammt, wir haben mitunter sogar ein Handy auf die Prototypen-Platine gelegt und telefoniert während einer Datenübertragung.
Nop schrieb: > Das verstehst Du falsch. Ein vernünftiges Design hat nichts mit einer > Programmiersprache zu tun. Es ist nur so, daß Du versuchst, Deine > Designschwächen mit Programmiersprachen zu kaschieren, weswegen Du > solche brauchst, die das unterstützen. Ich brauche das nicht und > vermisse das daher auch nicht. Ich brauche nichts zu kaschieren! Die von mir erstellten Programme werden in meiner Firma seit 15 Jahren weltweit eingesetzt. Von einigen Programmen wußte ich noch nicht mal, daß sie soweit verbreitet sind, da ich sie nur als Hilfstools für mich geschrieben habe und sie nur einem kleinen Kollegenkreis überlassen habe. Ich kann also nicht wirklich viel falsch gemacht haben. Das mal nur so nebenbei. Ich mache bestimmt nicht so perfekte Programme wie Du, aber im Gegensatz zu Dir bin ich auf dem Boden der Tatsachen geblieben und erhebe mich nicht über andere. Deine Arroganz ist kaum noch zu toppen. So einen Besserwisser wie Dich habe ich hier im Forum ja überhaupt noch nicht angetroffen. Ich befürchte mal Dein Nickname ist nicht nur Dein Nickname sondern Programm und Dir muß ich den Begriff NOP bestimmt nicht erklären. Zeno
Zeno schrieb: > Ich brauche nichts zu kaschieren! Die von mir erstellten Programme > werden in meiner Firma seit 15 Jahren weltweit eingesetzt. Hauptsache, sie sind nicht gerade in C geschrieben.. oder gar C++. Wenn's in Pascal o.ä. ist, wieso nicht. > Ich mache bestimmt nicht so perfekte Programme wie Du, aber im Gegensatz > zu Dir bin ich auf dem Boden der Tatsachen geblieben und erhebe mich > nicht über andere. Doch, das tust Du, und das wurde Dir hier auch schon gesagt. Du hast z.B. zur Schau gestellt, daß Du keine Ahnung von C hast, aber schonmal Compilerfehler diagnostizierst. > Deine Arroganz ist kaum noch zu toppen. So einen Besserwisser wie Dich > habe ich hier im Forum ja überhaupt noch nicht angetroffen. Kann ich auch nichts dafür, daß ich mit meinem Programmansatz nunmal nicht in derselben Liga spiele wie Du. Sorry, wenn Dir das ein Egoproblem bereitet, aber in meiner Freizeit bin ich nicht gezwungen, mit den Egoproblemen anderer Leute betüddelnd umzugehen. Wenn jemand wie W.S. über C herzieht, stimme ich dem zwar auch so nicht zu, aber zumindest hat er auch was gerissen. Und im Gegensatz zu Dir weiß so jemand auch, was er kritisiert, während Du ja nichtmal Grundlagen dessen verstanden hast, was Du da kritisiert.
Was ein Kindergarten. Können wir uns darauf einigen, dass Gabeln die schlechteren Harken sind weil man mit Schaufeln nicht so gut schneiden kann?
A. K. schrieb: > Jörg W. schrieb: >> Selbst Pascal braucht sie (write[ln], read[ln]). > > Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in > Pascal selbst geschrieben? Ganz einfach:
1 | procedure Writeln(Args: Arguments); |
2 | |
3 | procedure WriteLn(var F: Text; Args: Arguments); |
4 | |
5 | procedure ReadLn(Args: Argument); |
6 | |
7 | procedure ReadLn(var F: Text; Args: Arguments); |
Hier nachzulesen: http://www.freepascal.org/docs-html/rtl/system/writeln.html Bevor du aber jetzt den Quellcode von Free Pascal herunterlädst, um nachzusehen, was "Arguments" wohl für ein Datentyp ist, hier ein Ausschnitt aus der Datei system.fpd, auf die im obigen Link verwiesen wird (man beachte den Kommentar am Anfang):
1 | { |
2 | […] |
3 | This File contains extra, phony declarations used in fpdoc. |
4 | […] |
5 | **********************************************************************} |
6 | |
7 | […] |
8 | Procedure Read (Var F : Text; Args : Arguments); |
9 | Procedure ReadLn (Var F : Text; Args : Arguments); |
10 | Procedure Read (Args : Arguments); |
11 | Procedure ReadLn (Args : Arguments); |
12 | […] |
13 | Procedure Write (Args : Arguments); |
14 | Procedure Writeln (Args : Arguments); |
15 | Procedure Write (Var F : Text; Args : Arguments); |
16 | Procedure WriteLn (Var F : Text; Args : Arguments); |
17 | […] |
Natürlich sind diese "Prozeduren" in Wirklichkeit gar keine und deswegen auch nirgends als solche implementiert. Auch "Arguments" ist ein reiner Phantasietyp, der nirgends definiert ist.
Nop schrieb: > Wenn jemand wie W.S. über C herzieht, stimme ich dem zwar auch so nicht > zu, aber zumindest hat er auch was gerissen. Über dieses Statement wird sich W.S. aber freuen, aber es wird ihn nicht vom Hocker reißen. Und ob ich etwas gerissen habe oder nicht dürftest Du nicht beurteilen können, dafür kennst Du mich viel zu wenig. Aber nein ich habe es vergessen - Du kannst das natürlich. Und was Du mir zugestehst oder nicht interessiert mich herzlich wenig. Ich kann auch ganz gut ohne Deine Statements und werde nicht mehr näher auf Deine Posts eingehen, da es vergeudete Zeit ist. Zeno
Zeno schrieb: > werde nicht mehr näher > auf Deine Posts eingehen, da es vergeudete Zeit ist. Genau. Kümmer mich mal lieber um die mehrfach auch von Anderen verlangten Quellennachweise für Deine Behauptung, daß in C ein if-Statement einen Bollean verlangt. Den Quellennachweis für Deine Ahnungslosigkeit hast Du ja immer noch nicht geliefert. Alternativ bilde Dich mal ein bißchen fort, auch gut.
Yalu X. schrieb: > Mit Exceptions reduziert sich der ganze Aufwand auf die eigentliche > Abfrage des UART-Registers, das Auslösen der Exception bei erkanntem > Fehler und das Abfangen des Fehlers auf der Unterprogrammebene, wo auch > die Reaktion auf den Fehler ausgelöst wird. Alle Unterprogramme, die in > der Hierarchie dazwischen liegen, bleiben von der Fehlerbehandlung > völlig unberührt. Fehlerbehandlungscode gibt es also nur dort, wo der > Fehler entsteht und dort, wo er behandelt wird, sonst nirgends. Das > erhöht die Übersicht und die Erweiterbarkeit des Programms beträchtlich. Ein Problem ergibt sich nur, wenn jede Ebene denkt, die nächsthöhere behandelt die Exception, und auf der höchsten Ebene wurde es vergessen bzw. kann man nichts sinnvolles mehr damit anfangen. Und das kommt offenbar öfter vor, denn ich erlebe es nicht so selten, dass Programme sich mit einer Exception beenden. Zeno schrieb: > Oh da sieht man das Du von der Praxis halt weit entfernt bist. Messwerte > mit Null sind durchaus möglich und auch kein Fehler. Das kommt drauf an. Natürlich kann eine Null ein korrekter Eingabewert sein. Dann ist aber der Algorithmus, der dadurch dividieren muss, fehlerhaft und muss überarbeitet werden. Es kann aber auch sein, dass die Null eigentlich nicht erlaubt ist. Dann ist sie sehr wohl ein Fehler, und den fängt man dann ab, bevor sie in den Algorithmus geht und wartet nicht, bis sie einem danach um die Ohren fliegt. A. K. schrieb: > Nop schrieb: >> Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare >> Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus". > > Egal wie oft du Inputs validierst: Ob es das Item überhaupt gibt, dessen > Kennzeichnung übergeben wird, weisst du erst, wenn du danach fragst. Ist > ein Fehlschlag selten und unerwartet, dann kann es wesentlich > übersichtlicher sein, auf einem recht hohen Layer damit umzugehen, als > den Erfolg in allen Layern zwischendrin jedesmal abzufragen. Für mich ist der Fehler auf unterschiedlichen Layern in der Regel auch unterschiedlich. Nehmen wir gerade mal die Division durch Null. Was soll ein höheres Layer mit der Information anfangen, dass irgendwo weiter unten durch Null dividiert wurde? Für das höhere Layer müßte es eher sowas wie z.B. ein InvalidInputData oder so sein. Ich muss also auf den Zwischenlayern die Exception fangen und dann eine entsprechend aufbereitete Exception werfen. Damit hab ich dann nichts gewonnen gegenüber dem Hochreichen von Fehlercodes. A. K. schrieb: > Jörg W. schrieb: >> Selbst Pascal braucht sie (write[ln], read[ln]). > > Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in > Pascal selbst geschrieben? War das nicht so, dass diese Funktionen in "klassischem" Pascal gar nicht so geschrieben werden können? Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber für einzelne Teile der Sprache selbst dann trotzdem genutzt werden. Das ist ähnlich wie bei Java mit seiner fehlenden Operator-Überladung für Klassen, aber einem überladenen Operator + für die String-Klasse. Da werden Elemente von den Machern der Sprache offenbar für unnötig definiert, aber selber kommen sie nicht ohne aus. Was ist das denn für ein Irrsinn?
Rolf M. schrieb: > War das nicht so, dass diese Funktionen in "klassischem" Pascal gar > nicht so geschrieben werden können? Das war der tiefere Sinn der Frage. ;-)
Yalu X. schrieb: > A. K. schrieb: >> Jörg W. schrieb: >>> Selbst Pascal braucht sie (write[ln], read[ln]). >> Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in >> Pascal selbst geschrieben? > > Ganz einfach: Du unterschlägst, daß es prinzipbedingt unmöglich ist, derartige Funktionen (oder meinetwegen "Prozeduren") in Pascal selbst zu schreiben.
Rolf M. schrieb: > Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer > Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber > für einzelne Teile der Sprache selbst dann trotzdem genutzt werden. Jein; bei Pascal eigentlich nicht, weil Pascal als Lehrsprache gedacht war. Deswegen ist das Flair von "betreutem Programmieren" in dem Fall noch OK. Das Problem war dann halt, daß die ganzen praktisch nötigen Erweiterungen proprietär reingefrickelt wurden, wodurch man diverse halbwegs taugliche, aber zueinander inkompatible Pascal-Dialekte hatte. Plattform-Portabilität war damit Essig, was einer der Gründe ist, wieso Pascal das Rennen nicht gemacht hat. Was mir im reinen Wirth-Pascal gefehlt hat, ist auch freier Umgang mit Pointern. Pointercasting, Pointherarithmetik, Bitgepfriemel auf Pointer. Sonst muß man z.B. für ein schnelles memcpy/memset ja in Assembler gehen, während man das in C auch in der Hochsprache schreiben kann.
.. ach ja, und daß man nicht vorzeitig aus Schleifen rauskam in Pascal, weil es weder break noch continue gab, nervte auch. Break mußte man sich mit irgendwelchen zusätzlichen Flag-Fiddeleien emulieren, was langsamer und unübersichtlicher war. Dieselbe Katastrophe bei Fehlerbehandlung, weil man kein goto hatte; nichtmal mehrfache returns in einer Funktion. Das Ergebnis waren riesige Blockverhaue mit diversem nesting. Als Lehrsprache egal, denn wenn man sich auf die Implementation grundlegender Algorithmen beschränkt, braucht man auch keine Fehlerbehandlung. Aber in der Praxis echt nervig. Weswegen das dann ja auch in Form diverser inkompatibler Dialekte reingefrickelt wurde. Mit dem Ergebnis, daß man dann zwar halbwegs dieselben Fehler wie in C machen konnte, nur halt ohne die Portabilität.
Zeno schrieb: > Ich brauche nichts zu kaschieren! Die von mir erstellten Programme > werden in meiner Firma seit 15 Jahren weltweit eingesetzt. Von einigen > Programmen wußte ich noch nicht mal, daß sie soweit verbreitet sind, da > ich sie nur als Hilfstools für mich geschrieben habe und sie nur einem > kleinen Kollegenkreis überlassen habe. > Ich kann also nicht wirklich viel falsch gemacht haben. Ja, Nivau sieht von unten her immer wie Arroganz aus, nicht war? Das mit den ungewollt international eingesetzten Programmen, die nicht dafür gedacht waren, geht mir auch so und es kamen nie klagen. Dabei weiß ich ganz genau, daß das Schrott ist, den ich schnell zusammen gehackt habe. Das beweist also keinerlei Qaulität. Also komm mal von deinem hohen Ross runter und lande wieder in der Realität.
Nop schrieb: > Was mir im reinen Wirth-Pascal gefehlt hat, ist auch freier Umgang mit > Pointern. Pointercasting, Pointherarithmetik, Bitgepfriemel auf Pointer. Dir haben in Pascal also die Fehler von C gefehlt? ;-)
:
Bearbeitet durch User
A. K. schrieb: > Du meinst, dir haben in Pascal genau all jene Fehler gefehlt, die es in > C gab? ;-) Naja was heißt gefehlt - mit den proprietären Erweiterungen konnte man ja das Pascalmüsli mit Inline-Assembler umgehen. q: Leider war man damit dann nicht nur im jeweiligen Pascaldialekt gefangen, sondern auch noch auf der CPU.
Rolf M. schrieb: > Ein Problem ergibt sich nur, wenn jede Ebene denkt, die nächsthöhere > behandelt die Exception, und auf der höchsten Ebene wurde es vergessen > bzw. kann man nichts sinnvolles mehr damit anfangen. Und das kommt > offenbar öfter vor, denn ich erlebe es nicht so selten, dass Programme > sich mit einer Exception beenden. Stimmt, das habe ich auch schon oft erlebt. Wenn der Programmierer aber vergisst, eine Fehlerbehandlung zu implementieren, kann man das nicht den Exceptions anlasten. Verwendet er statt Exceptions Returncodes und vergisst, diese an geeigneter Stelle auszuwerten, hat man das Problem genauso, nur dass das Programm dann nicht mit einer Diagnosmeldung abbricht. Rolf M. schrieb: > War das nicht so, dass diese Funktionen in "klassischem" Pascal gar > nicht so geschrieben werden können? Ja, aber auch in "modernem" Object-Pascal geht das m.W. nicht. > Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer > Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber > für einzelne Teile der Sprache selbst dann trotzdem genutzt werden. Das ist Ansichtssache. Wenn man WriteLn nicht als Bibliotheksfunktion (wie bspw. printf in C), sondern als Konstrukt der Sprache selber ansieht, löst sich dieser Widerspruch auf. Selbst als variadische Funktion wäre WriteLn nicht implementierbar, da es ja noch die durch Doppelpunkt getrennte Formatparameter gibt, die zu einer völlig anderen Syntax führen. Die Philosophie, möglichst viele Sprachfeatures in Bibliotheksfunktionen auszulagern, kam erst so richtig mit C auf. Seither ist man gewohnt (und erwartet es sogar), dass zumindest die I/O-Funktionen komplett aus der Bibliothek kommen. Auch in Python gab es langezeit das Schlüsselwort print, dessen Argumente nicht geklammert werden müssen. Mittlerweile (in Python 3) ist print aber eine ganz normale Funktion (deren Argumente deswegen in Klammern geschrieben werden müssen). Yalu X. schrieb: > A. K. schrieb: >> Jörg W. schrieb: >>> Selbst Pascal braucht sie (write[ln], read[ln]). >> Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in >> Pascal selbst geschrieben? > > Ganz einfach: Du unterschlägst, daß es prinzipbedingt unmöglich ist, derartige Funktionen (oder meinetwegen "Prozeduren") in Pascal selbst zu schreiben. Nicht ich unterschlage das, sondern die Free-Pascal-Doku, aus der ich diese Pseudodeklarationen kopiert habe ;-)
Zeno schrieb: > Und das ist nicht der einzige Designfehler in C. Das geht weiter mit den > fehlenden Strings die durch das unsägliche Zeichenarray dargestellt > werden müssen, welches zu allem Überfluß noch durch das Nullzeichen > abgeschlossen werden muß, weil C nicht wirklich mit Arrays umgehen kann > (sage nicht nur ich) und das Stringende glatt verpassen würde. > Das sind Designfehler in C die einem sofort auffallen, wenn man von > einer anderen Sprache kommt. Dazu muß man kein C Guru sein. Der muß man > allerdings sein, wenn man die entarteten C-Konstrukte verstehen will. Genau für so lowlevel Zeug ist C gemacht worden, um nicht mit assembler arbeiten zu müssen, und bei kleinen controleren, oder für sehr Hardwarenahe Sachen ist C einfach das Beste Werkzeug, neben dem Assembler. Natürlich macht man sich damit die Finger schmutzig, es geht halt nicht alles im Elfenbeinturm, einer muss mal mit der Arbeit anfangen. Oder anders gesagt, nimm deine bevorzugte Sprache und dann das Datenblatt der Hardware und Schreibe mal ein Programm um deinen String im Speicher zu Kopieren, Verknüpfen, etc. Da musst du ersteinmal überlegen, wie du den String im Speicher eigentlich ablegen und Interpretieren kannst, oder anders gesagt, was eigentlich ein String auf der Hardwareebene ist.
mec schrieb: > Da musst du ersteinmal > überlegen, wie du den String im Speicher eigentlich ablegen und > Interpretieren kannst, Weshalb? Wenn Strings primäre Sprachobjekte sind, oder Objekte im OOP, dann gibt es auch Methoden, um daraus Substrings oder Zeichen rauszufischen und zu ersetzen.
:
Bearbeitet durch User
mec schrieb: > Da musst du ersteinmal > überlegen, wie du den String im Speicher eigentlich ablegen und > Interpretieren kannst, oder anders gesagt, was eigentlich ein String auf > der Hardwareebene ist. Übrigens sind Pascalstrings noch kranker, als C-Strings je sein werden. Denn zwar gibt es einen Datentyp "string", bei Pascal. Das ist aber Kosmetik, der ist unter der Haube definiert als ein array of char. Und zwar alle in derselben Länge. Der Grund ist, daß Pascal idiotischerweise die Länge eines Arrays als Teil seines Datentyps ansieht und dann mit dem strengen Typensystem die Sache vollends unbrauchbar macht. Also einfach alle Strings mit maximaler Länge definieren und wegverstecken, damit der Nutzer das Elend nicht sieht. Wobei die maximale Länge natürlich 256 ist, weil das Längenbyte eben nur 8 bit hat. AUch so eine grandiose Idee. Der Irrsinn mit den Arrays hat übrigens auch zur Folge, daß man keine generische Sortierroutine auf Arrays mit einem bestimmten Grundtyp, aber unterschiedlicher Längen machen kann. Ach was soll's, dann definiert man halt einfach immer alle Arrays in derselben Länge, nur um den Schlägen des Typensystems auszuweichen. Oder, Trommelwirbel, man umgeht das mit Pointern. Moooment, war nicht gerade ein Hauptkritikpunkt an C das Herummachen mit Pointern? Tja, deswegen. Damit sowas geht.
Zeno schrieb: > Und das ist nicht der einzige Designfehler in C. Das geht weiter mit den > fehlenden Strings die durch das unsägliche Zeichenarray dargestellt > werden müssen, welches zu allem Überfluß noch durch das Nullzeichen > abgeschlossen werden muß, weil C nicht wirklich mit Arrays umgehen kann > (sage nicht nur ich) und das Stringende glatt verpassen würde. Hast du schon mal überlegt was ein String eigentlich ist? Als Zeichenfolge oder Zeichenkette wird es auf Deutsch übersetzt. Das kann man wieder zurückübersetzen als 'array of char'. Also genau so, wie es in C dargestellt wird. Und da man keine ganzen Speicherbereiche als Parameter übergeben kann, nimmt man dafür den Zeiger darauf. Es gibt übrigens keine Programmiersprachen, in der Strings nicht als Zeiger übergeben werden. Nur ist es in anderen Sprachen oft ein Zeiger auf eine ganze Struktur bzw Objekt, während in der C-Konvention ein Zeiger auf die Anfangsadresse ausreicht. Damit wird die effektivste und schnellste Stringbearbeitung möglich. > Das sind Designfehler in C die einem sofort auffallen, wenn man von > einer anderen Sprache kommt. Dazu muß man kein C Guru sein. Der muß man > allerdings sein, wenn man die entarteten C-Konstrukte verstehen will. Für manche ist eben alles, was sie nicht verstehen oder nicht verstehen wollen "entartete" Kunst.
A. K. schrieb: > Weshalb? Wenn Strings primäre Sprachobjekte sind, oder Objekte im OOP, > dann gibt es auch Methoden, um daraus Substrings oder Zeichen > rauszufischen und zu ersetzen. Man muß trotzdem verstehen, wie die implementiert sind, sonst gibt es herbe Skalierungseffekte. Extrem beliebt in Dateimanagern aller Art, wenn dort nur Methoden irgendwie zusammengeleimt wurden. Funktioniert mit 50 Dateien in einem Verzeichnis und hängt dann stundenlang, wenn es mehrere tausend Dateien werden.
Jobst Q. schrieb: > Damit wird die effektivste und schnellste Stringbearbeitung möglich. Strings mit mitgeschleppter Länge sind oft schneller als die C Methode mit 0-Terminierung.
:
Bearbeitet durch User
W.S. schrieb: > Oder anders herum: Du magst C mehr als Pascal, aber kann C deshalb > Objektorientiertheit? Oder Exceptions? Oder Strings? nein, natürlich > nicht. Da kann ich nur sagen: Gott sei Dank! Ich denke mir nur mal den Schwachsinn aus, wenn bei jedem kleine Controller eine dynamische String-Unterstützung oder Exceptions im Default dabei wäre. Und das bei auf ein par kB begrenztem Heap. Nach 3 Tagen geht dann irgendwie nichts mehr nur weil der Heap fragmentiert ist... Nein, ich und wahrscheinlich 99,9% aller embedded Entwickler wollen das sicher nicht, sonst würde es das geben. Wem C nicht reicht der kann seine Quellen als C++ übersetzen und selbst entscheiden auf welchem Level man sich bewegt. Dann hat er auch Strings, Exceptions und viele andere Sachen. Aber nur wenn er will. Ich finde die ganzen Versuche JavaScript, LUA, Pascal, Basic oder wie sie alle heißen auf die kleine Hardware ohne vernünftige Speicherverwaltung zu implementieren absoluten Käse. Bisher waren auch alle Versuche entweder relativ erfolglos oder hatten ein kurzes Leben. Wenn in Zukunft selbst der kleinste Controller Mega- oder Gigabytes an Ram hat sieht das anders aus. Aber dann bestehen Programme die heute 10000 Zeilen in der Summe haben aus 10Mio. Und da soll die Fehlerwahrscheinlichkeit kleiner sein? Und das alles nur weil man zu blöd ist "for(;;)" zu verstehen oder weil man bei "while(a=read())" am Zweifeln ist ob Fehler oder gewollt? Wenn es dann mal soweit ist, dass in einem einfachen digitalen Zeitrelais ein Linux-Kernel werkelt nur weil C etwas von Vorgestern ist, dass nur noch die senilen alten Säcke verwenden... , ja dann gebe ich mich geschlagen und W.S. Recht.
A. K. schrieb: > Strings mit mitgeschleppter Länge sind oft schneller als die C Methode > mit 0-Terminierung Klar wer das in dieser Form braucht kann sich in mit wenigem Aufwand eine kleine Lib bauen die ständige strlen() Aufrufe verhindert. Dafür gibt es Strukturen oder Klassen(C++). Die Länge von konstanten Zeichenketten im Flash weiß der Compiler selbst und kann damit arbeiten.
A. K. schrieb: > Jobst Q. schrieb: >> Damit wird die effektivste und schnellste Stringbearbeitung möglich. > > Strings mit mitgeschleppter Länge sind oft schneller als die C Methode > mit 0-Terminierung. Für einzelne Funktionen mag das stimmen, wenn es um sehr lange Strings geht. Dafür muss bei jeder Zuweisung oder Änderung die Länge neu berechnet werden. Das ist ein hoher Verwaltungsaufwand, der sich weder in Geschwindigkeit noch in Codegröße bezahlt macht. In der Praxis der Stringbearbeitung, zB dem Einlesen einer Konfigurationsdatei, wird die Länge nur in seltenen Fällen gebraucht. Weder zum Überspringen von Whitespace (Leerzeichen,Tabs usw) noch zum Abtrennen von Kommentaren ist die Länge nützlich. Der Kommentar ist für das Programm nicht interessant, also brauch es auch seine Länge nicht. Und wenn die Länge mal gebraucht wird, zB um in eine Datei zu schreiben, kann sie oft auch durch die vielgeschmähte Pointerarithmetik schnell berechnet werden.
Jobst Q. schrieb: > Für einzelne Funktionen mag das stimmen, wenn es um sehr lange Strings > geht. Dafür muss bei jeder Zuweisung oder Änderung die Länge neu > berechnet werden. Wirklich fies ist der Anwendungsfall, wenn man an einen C-String oftmals andere Strings hintendranhängen will. Wenn man das einfach mit strcat direkt macht, wird das lahm. Dafür ist strcat nicht gedacht. Dann schreibt man sich eine Funktion, die nach dem Dranhängen einen Zeiger auf die terminierende Null zurückliefert. Der nächste String kann genau dort dann angehängt werden, ohne daß man den ganzen String von vorne bis zur Null durchloopen müßte.
Nop schrieb: > Jobst Q. schrieb: >> Für einzelne Funktionen mag das stimmen, wenn es um sehr lange Strings >> geht. Dafür muss bei jeder Zuweisung oder Änderung die Länge neu >> berechnet werden. > > Wirklich fies ist der Anwendungsfall, wenn man an einen C-String oftmals > andere Strings hintendranhängen will. Wenn man das einfach mit strcat > direkt macht, wird das lahm. Dafür ist strcat nicht gedacht. > > Dann schreibt man sich eine Funktion, die nach dem Dranhängen einen > Zeiger auf die terminierende Null zurückliefert. Der nächste String kann > genau dort dann angehängt werden, ohne daß man den ganzen String von > vorne bis zur Null durchloopen müßte. Genau so mache ich das auch mit konstruierenden Stringfunktionen. Bei fertigen Funktionen wie snprintf, die die Länge zurückgeben heißt es dann eben t+= snprintf(t,lim-t,...);
Yalu X. schrieb: >> Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer >> Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber >> für einzelne Teile der Sprache selbst dann trotzdem genutzt werden. > > Das ist Ansichtssache. Naja, wenn es da benötigt wird, dann wird es auch für Anwender sinnvoll sein, also ist es meines Erachtens ein Fehler, dem die selben Möglichkeiten zu verwehren. > Wenn man WriteLn nicht als Bibliotheksfunktion (wie bspw. printf in C), > sondern als Konstrukt der Sprache selber ansieht, löst sich dieser > Widerspruch auf. Das finde ich nicht. Im Gegenteil finde ich es unelegant, mangels geeignter Sprachfeatures sowas zu einem speziellen Konstrukt machen zu müssen, statt es auf eine Basis zu stellen, die jedem Benutzer der Sprache zur Verfügung steht. > Selbst als variadische Funktion wäre WriteLn nicht implementierbar, da > es ja noch die durch Doppelpunkt getrennte Formatparameter gibt, die zu > einer völlig anderen Syntax führen. Nun gut, das könnte man ja auch als Manko sehen. Noch mehr Sonderbehandlung, die dafür nötig ist. Nicht dass variadische Funktionen, wie sie in C umgesetzt sind und die Formatstring-Geschichten das Nonplusultra wären, aber printf lässt sich wenigstens als normale Funktion ohne irgendwelche Sonderlösungen implementieren. > Die Philosophie, möglichst viele Sprachfeatures in Bibliotheksfunktionen > auszulagern, kam erst so richtig mit C auf. Seither ist man gewohnt (und > erwartet es sogar), dass zumindest die I/O-Funktionen komplett aus der > Bibliothek kommen. Ich halte das so auch für sinnvoller. Natürlich ist mir bewusst, dass das alles mal vor Jahrzehnten noch nicht so klar war, wie heute.
Rolf Magnus schrieb: > Nun gut, das könnte man ja auch als Manko sehen. Noch mehr > Sonderbehandlung, die dafür nötig ist. Nicht dass variadische > Funktionen, wie sie in C umgesetzt sind und die Formatstring-Geschichten > das Nonplusultra wären, aber printf lässt sich wenigstens als normale > Funktion ohne irgendwelche Sonderlösungen implementieren. Und wenn man embedded unterwegs ist und sich nicht selbst um printf kümmert hat man entweder eine Krücke aus der newlib bei der gefühlt 80% der Anwender nicht wissen wo und wie sie ihren dynamischen Speicher herkriegt, oder es wird gemault wenn printf nicht geht. Deshalb würde ich printf auch nie als etwas zur Sprache C gehörendes betrachten. Es ist und bleibt eine Funktion aus einer Lib. Wenn mein printf keine double ausgeben muss, macht es auch keinen Sinn 1-2K dafür in den Flash zu packen. Da reicht auch eine schmale Implementierung die auf das sbrk ganz verzichten kann.
temp schrieb: > Da reicht auch eine schmale Implementierung die auf das sbrk ganz > verzichten kann. Ist ja nun aber nicht so, dass es die nicht gäbe. Ja, man könnte sich allemal technisch elegantere Lösungen wünschen, bei denen der Linker bereits entscheiden kann, was im Hintergrund tatsächlich an Konvertierungen benötigt wird. Aber eins muss man printf() & Co lassen (auch, wenn man sich dann mal Pascal's WriteLn nach vielen Jahren wieder ansieht): aus Benutzersicht ist es ein verdammt mächtiges und trotzdem immer noch hinreichend einfach zu bediendendes Werkzeug, das man eigentlich selbst bei Embedded oft genug nicht mehr missen möchte. Die Tatsache, dass man es (dank der v-Varianten der Funktionen) gewissermaßen auch noch ganz offiziell „beerben“ kann (im bereits genannten Gegensatz zu Pascal), macht es im praktischen Leben nochmal ein wenig nützlicher.
Rolf Magnus schrieb: >> Die Philosophie, möglichst viele Sprachfeatures in Bibliotheksfunktionen >> auszulagern, kam erst so richtig mit C auf. Seither ist man gewohnt (und >> erwartet es sogar), dass zumindest die I/O-Funktionen komplett aus der >> Bibliothek kommen. > > Ich halte das so auch für sinnvoller. Natürlich ist mir bewusst, dass > das alles mal vor Jahrzehnten noch nicht so klar war, wie heute. Auch ich finde das nach Abwägung aller Vor- und Nachteile (etwas) besser. Den Hauptnachteil von printf genenüber WriteLn sehe ich darin, dass es eine Funktion ist, die viel mehr kann als i.Allg. tatsächlich gebraucht wird und deswegen sehr groß ist, wie auch schon von "temp" angemerkt wurde: temp schrieb: > Wenn mein printf keine double ausgeben muss, macht es auch keinen Sinn > 1-2K dafür in den Flash zu packen. Auf PCs ist das kein Problem, auf einem AVR schon. Bei WriteLn kann der Compiler je nach Datentyp der Argumente die jeweils passenden Ausgaberoutinen aus der Bibliothek verwenden. Beim GCC ist printf mittlerweile eine Built-In-Funktion und damit streng genommen wie in Pascal ein Bestandteil der Sprache. Es gibt aber zwei wesentliche Unterschiede: 1. Das Built-In-printf folgt nach wie vor genau der Syntax für Funktionsaufrufe, so dass man außer einem Geschwindigkeitsvorteil in manchen Fällen keinen Unterschied zum Bibliotheks-printf merkt. 2. Der GCC macht zwar kleinere Optimierungen, indem er, wo dies möglich ist, den printf durch einen putchar- oder puts-Aufruf ersetzt, eine Optimierung in Anbhängigkeit von den Argumenttypen ist aber (noch) nicht implementiert. Sollte dies eines Tages geschehen, würden die Vorteile des klassischen printf mit denen des WriteLn vereint, und es gäbe noch einen Grund weniger, Pascal zu benutzen ;-) Eine große Schwäche von Pascal im Zusammenhang mit WriteLn ist, dass es keinen entsprechenden Befehl gibt, der das formatierte Ergebnis nicht ausgibt, sondern in einen String schreibt, also das, was man in C mit sprintf machen würde. Die Delphi-Entwickler haben dieses Problem zwar erkannt, haben sich aber – warum auch immer – gegen die Erweiterung von WriteLn entschieden, obwohl dies eigentlich naheliegend gewesen wäre:
1 | { Standard-Pascal, Ausgabe auf der Konsole } |
2 | procedure Writeln(Args: Arguments); |
3 | |
4 | { Standard-Pascal, Ausgabe in eine Textdatei } |
5 | procedure WriteLn(var F: Text; Args: Arguments); |
6 | |
7 | { Erweiterung, Ausgabe in einen String } |
8 | procedure WriteLn(var S: String; Args: Arguments); |
Stattdessen wurden die beiden neuen Bibliothekfunktionen Format und StrFmt eingeführt: http://www.freepascal.org/docs-html/rtl/sysutils/format.html http://www.freepascal.org/docs-html/rtl/sysutils/strfmt.html Witzigerweise entsprechen diese Funktionen einschließlich der Syntax des Formatstrings fast genau der sprintf-Funktion in C, nur dass die Argumente nicht direkt, sondern in einem Array variabler Länge übergeben werden, damit die Argumentzahl konstant bleibt. Es gibt also zwei syntaktisch völlig verschiedne Formatierungskonzepte, deren Auswahl nicht etwa davon abhängt, was man wie formatieren möchte, sondern lediglich davon, was man nach erfolgter Formatierung mit dem Ergebnis tun möchte. Das mutet schon sehr schräg an und zeigt, dass Pascal genauso wie C mit Altlasten zu kämpfen hat, die eigentlich überholt angesehen werden, aber aus Gründen der Kompatibilität immer noch mitgeschleppt werden müssen. Dagegen ist es doch Pipifax, ob man nun for(;;), while(1) oder sonst etwas für eine Endlosschleife schreibt :)
C ist schon ganz nett für sehr hardwarenahes Zeug wie µC, Kernelentwicklung. Aber ich tendiere immer mehr zu C++. Typsicherheit, Referenzen und Templates sind einfach zu praktisch. Gerade eine Möglichkeit, generische Datenstrukturen zu schreiben (Binäre Bäume, Verkettete Listen...), fehlt mir einfach in C. Es gibt ja keine Generics oder Templates in C (bitte keine Präprozessor Geschichten grusel). So habe ich, nachdem ich schon zum dritten Mal eine Verkettete Liste für meinen Kernel implementiert habe, entnervt aufgegeben. Werde das ganze jetzt wohl zu C++ portieren, damit werde ich wahrscheinlich glücklicher. Disclaimer: Natürlich ist es prinzipiell möglich. Aber bisher habe ich noch keine zufriedenstellende Lösung gefunden. Die Umsetzung mit void* und Präprozessor ist relativ umständlich von der Bedienung. Mit C++ lässt sich das sehr elegant machen.
282 Beiträge??? Habt ihr keine anderen Probleme (bzw. wichtigeres)??? EDIT: Too late
:
Bearbeitet durch User
Nop schrieb: > Nö, sondern weil mich bei Pascal nach der Anfangszeit die Restriktivität > der Sprache zunehmend genervt hat. Ähem.. ich kann das nur so verstehen, daß du zu den Leuten gehörst, die zu allererst int main(... hinschreiben und sich dann sagen "ach mir wird schon noch was einfallen". Ist das so? Gehst du denn überhaupt nicht planvoll an deine Arbeit? Ich schon, bei mir werden zu allererst die Interfaces, Typen und Daten festgelegt und ein ganzes Stück später kommt das Fassen in einer Programmiersprache. Also schreib mal, was du unter Restriktivität denn überhaupt verstehst, daß selbige dich so genervt hat. Und wo hast du gegen den Compiler gekämpft? Ich sag dir mal eins: dein "sondern ich will, daß der Compiler das umsetzt, was ich sage, Punkt." ist so ziemlich das Falscheste, was man sich wünschen kann. Du solltest dir lieber wünschen, daß der Compiler dir das umsetzt, was du EIGENTLICH MEINST - und nicht das, was du tatsächlich sagst (bzw. schreibst). Glaub's mir! > Falsch, C99 beispielsweise hat auch portable Datentypen eingeführt. O jemine, schon wieder dieser unselige Krempel. Da hat überhaupt keiner irgendwas eingeführt, sondern es war die finale Kapitulation. Und zwar in der Form, daß man gesagt hat "Leute macht euch für eure partikuläre Architektur eine Headerdatei, wo ihr reinschreibt typedef unsigned long uint32_t; und so weiter. Sowas haben Legionen von Leuten zuvor schon längst gemacht mit u32 oder anderen selbstausgedachten Namen. Jedem C-Compiler ist das völlig schnurz. Er kennt all dieses Zeugs nur dann, wenn man ihm so eine Headerdatei zuvor in den Rachen geworfen hat. Sowas kann jeder, du könntest dir auf diese Weise auch nop32_t oder T32NOP oder sonstwas kreieren. Es ist eben Mumpitz, den jeder für sich machen kann und es ist NICHT eine tatsächliche Sprachänderung. Kapiere das mal. >> Pascal ist zukunftsfähig, C nicht. > Pascal hat seine Zukunft bereits hinter sich. Das sind mal wieder zwei verschiedene Dinge. Pascal hat die Fähigkeit, an zukünftige Anforderungen angepaßt zu werden. Die jüngere Vergangenheit hat gezeigt, daß das drin ist. Bei C war das eben an keiner Stelle nach ANSI mehr drin, siehe dein C99-Statement oben. Also, hier ging es um die Renovierbarkeit der Programmiersprache - nicht jedoch darum, ob sie künftig genommen oder abgelehnt werden wird. Das sind - wie gesagt - zwei verschiedene Dinge. Ich habe durchaus den Eindruck, daß Pascal irgendwann verschwunden sein wird - aber eben nicht aufgrund etwaiger Ungeeignetheit, sondern aufgrund mentaler Ablehnung. Ich sagte es ja schon: die Gründe für C sehe ich vorrangig im außertechnischen Bereich. > In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams > nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende > Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze. Sag's anders herum: Dort, wo man moderne Dinge wie GUI's benötigt - also überall auf allen PC's dieser Welt einschließlich aller Smartphones, Tablets, Navis - kann man C nicht wirklich einsetzen, denn dafür ist es zu poplig. Also bleibt noch die Welt der Kommandozeile, sprich Admi-Tätigkeit für die Server dieser Welt auf der Kommandozeile und Mikrocontroller ohne GUI. Ich hab mich früher genug beim Schreiben von Apps für Windows-CE per EVC abgequält um mir für diese Plattformen sowas wie Delphi sehnlichst gewünscht gehabt zu haben. > Exceptions brauche ich nicht, weil ich von vornherein Fehlerfälle nicht > zulasse. gröhl... mal im Ernst: was soll das bitte? > Strings gehen in C als C-Strings tadellos. Man kann sogar Pascalstrings > nachbilden, falls man das wollen sollte. Natürlich gibt die Sprache das > her. Jetzt übertreibst du es aber gar zu sehr. C kennt keine Strings. Punkt. C kennt lediglich Arrays von Zeichen und ich frag mich, ob ich dich überhaupt noch ernst nehmen sollte. Anmerkung zur Effizienz: Es ist geradezu grauselig, was für einen unnötigen Ressourcenverbrauch das unselige Nullbyte verursacht. Man schaue mal in ein x-beliebiges C-Programm hinein, das mit irgendwelchem Text umgeht. Wie oft dort wieder und wieder jede blöde Zeichenkette nach diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf intelligentere Weise zu merken, ist grauenvoll. Und das alles nur deshalb, weil C eben keine Strings kennt, wo man sowas auf effiziente Weise hätte erledigen können. Und jetzt kommen mir hier Leute mit der Behauptung, C sei effizient! > C ist als lowlevel-Sprache positioniert.. Ja. Sehe ich auch so. Aber man muß es ergänzen mit "Und wo ist eine High-Level-Sprache, die man eben für höhere Level benutzen kann? Und die so nebenbei den Bereich von C auch mit abdeckt?" Du hast unbeabsichtigt mir quasi aus dem Herzen gesprochen - teilweise. Low Level war früher, da wurde jedes Kilobyte an RAM mit Gold aufgewogen. Heutzutage braucht man was Anderes, nämlich Programmiersprachen, die: - moderne Programmelemente (GUI) und Beherrschung größerer Datenelemente (Objekte und Kapselung) besser machen als C - es dem Programmierer leicht machen und ihm so mehr Raum schaffen für seine eigentlichen höheren Ziele. Also ihn nicht mit lowlevel-Zerrigkeiten nerven, bis er sich an krude Syntax gewöhnt hat. Wir sind Menschen mit menschlichem Verstand und keine Maschinen - und es ist der falsche Weg, vom Menschen zu verlangen, daß er sich an die Maschine oder an krude Programmiersprachen gewöhnt. OK, sowas läßt sich nicht immer vermeiden, aber zmindest sollte man das nicht als Ziel aller Entwicklung sehen, sondern als etwas, das bei nächstbester Gelegenheit auszuräumen ist. Und da kommen wir zum TO zurück, dem sowas wie for(;;) unverständlich ist. Ich könnte da noch was anderes dranhängen wie z.B. sowas: void (*OnKey)(RCST* self, word *aKey); oder sowas: #define WDTC (*((volatile unsigned long *) 0xE0000004)) Wer schon länger C benutzt, wird das alles problemlos erkennen, aber wenn man mal wirklich ehrlich zu sich selbst ist, erkennt man an solchen Stellen sehr wohl, daß Formulierungen wie die obigen keine wirklich zukunftsträchtige gute Programmiersprache ausmachen. W.S.
W.S. schrieb: > #define WDTC (*((volatile unsigned long *) 0xE0000004)) Wie sieht denn der Zugriff auf ein Prozessor-IO-Register in Standard-Pascal aus?
Schade dass hier anscheinend niemand Ada kann. Ich hatte nämlich den Eindruck gewonnen, dass es weit besser zu Controllern passt.
A. K. schrieb: > Ich hatte nämlich den Eindruck gewonnen, dass es weit besser zu > Controllern passt. Ja, vermutlich schon. Es gab ja auch mal Ansätze für eine Portierung von GNU Ada auf den AVR, aber so wirklich weit gekommen waren sie wohl auch nicht. AVR-Ada Hmm, der Artikel ist so lange schon nicht mehr angefasst worden, dass der Wiki-Link nach Sourceforge stale ist. :( Ich korrigier' ihn mal.
W.S. schrieb: > Ähem.. ich kann das nur so verstehen, daß du zu den Leuten gehörst, die > zu allererst int main(... hinschreiben und sich dann sagen "ach mir wird > schon noch was einfallen". Ist das so? Nein. Du kannst es auch so verstehen, daß ich z.B. ganz gerne eine Sortierfunktion für typkompatible Arrays unterschiedlicher Länge hätte. Das geht in Pascal nicht, weil idiotischerweise die Arraylänge Teil des Typs ist. Die vollkommen kranke Stringlogik von Pascal will ich auch nicht mit maximal 256, und dann muß man auch alle Strings immer in derselben Länge nehmen, selbst wenn man nur 10 Zeichen braucht, weil das idiotische Typensystem von Pascal sonst zwischenhaut. Die Strings SIND Arrays. Ich möchte außerdem auch bei Bedarf Pointercasting haben, damit ich z.B. memory-mapped IO-Devices mit voller Breite ansprechen kann, weil der Durchsatz damit massiv höher geht. Auf nem ARM7-TDMI habe ich damit den Durchsatz zu einem Ethernetchip verdreifacht. Loop-Unrolling war natürlich auch mit von der Partie. Alleine schon eine schnelle Kopierschleife von Speicherbereichen mit Alignment-Check braucht Bitpfriemelei mit Pointern und Pointerarithmetik, das geht in Pascal allenfalls mit Inline-Assembler. Ich will nicht diesen Mist mit den Pascal-Schleifen, wo ich weder break noch continue habe und entweder umständlich mit Hilfsflags rumfiddeln muß oder unnütze Durchläufe habe. Ach ja, und for-loops gibt's auch nur mit Inkrement 1. Ich will auch nicht den Unfug, daß die Auswertung logischer Ausdrücke keine definierte Reihenfolge hat und man daher einen Nullpointercheck auf einem höheren Blocklevel als die Dereferenzierung machen MUSS. Prä- und Postinkrement gibt's auch nicht, was den ganzen Sermon noch mehr aufbläht. Hoffentlich ist der Compiler überhaupt schlau genug, das bei der Umsetzung in Maschinencode trotzdem hinzukriegen. Ich will auch mal temporär einen Buffer umwidmen können, was in C mit Pointercasting sehr elegant geht (wenn man im Kopf behält, daß die alten Inhalte des Buffers mit dieser Zugriffsart wegen Aliasing als undefiniert betrachtet werden müssen). Goto brauche ich hin und wieder, weil ich nicht wie in Pascal ein 120 Ebenen tiefes Nesting hingefrickelt haben will und auch nicht die Code-Duplikation bei gestackten Aufräumaktionen der Fehlerbehandlung will. Und noch einiges mehr, ich lasse es dabei aber mal bewenden. Ich brauche all das nicht IMMER, aber ich habe es als Werkzeug, weil C eben nicht auf Müsli beschränkt ist. Weil C nicht für Anfänger gemacht worden ist, die mit diesen Werkzeugen ohnehin nur Schaden anrichten würden. Ach ja, zu kritisieren an C im Hinblick auf fehlende Sachen wäre da natürlich die Abwesenheit des arithmetischen ifs, was es in Fortran mal gab, aber selbst dort wurde es dann rausgeworfen. Das hätte man gerne in C noch einbauen können. Also das if mit den drei Ausgängen. > Gehst du denn überhaupt nicht planvoll an deine Arbeit? Doch, und im Normalfall achte ich auf Typeneinheit. Es sind vielleicht 10% des Codes, wo ich die fieseren Seiten von C raushole. Aber der Punkt ist, mit Pascal gingen diese 10% nicht. Sind das lowlevel-Aspekte? Ja. Aber genau für lowlevel-Systemprogrammierung IST C GEMACHT. > Ich sag dir mal eins: > dein "sondern ich will, daß der Compiler das umsetzt, was ich sage, > Punkt." ist so ziemlich das Falscheste, was man sich wünschen kann. Nein, das ist exakt die Einstellung, für die C überhaupt erst gemacht wurde. Wenn Du nicht so denkst, dann laß es einfach sein, mit C zu programmieren, diese Sprache ist nicht für Dich gemacht. Ich rege mich eher auf, wenn der Compiler tut, wa sich ihm nicht gesagt habe. Beispielsweise die total kaputte Inline-Logik des GCC, die im Wesentlichen tut, was sie will - es sei denn, ich halte ihn mit haufenweise Funktionsattributen im Zaum. > Es ist eben Mumpitz, den jeder für sich machen > kann und es ist NICHT eine tatsächliche Sprachänderung. Kapiere das mal. Man BRAUCHT dafür auch keine Sprachänderung, kapiere das mal. Man muß nicht jeden Schnickschnack in die Sprache reinstopfen. Der Punkt ist, ja das haben vorher alle gemacht. IRGENDWIE. Das ist jetzt einheitlich. > Das sind mal wieder zwei verschiedene Dinge. Pascal hat die Fähigkeit, > an zukünftige Anforderungen angepaßt zu werden. Pascal hat die Fähigkeit, komplett zu verschwinden, und ist auf einem guten Weg dahin. Eigentlich IST Pascal längst tot, weil die Sprache dermaßen untauglich war, daß sie an allen Ecken mit zu nichts kompatiblen Dialekt-Erweiterungen aufgebohrt wurde. Mit Pchar hat man in manchen Dialekten übrigens endlich auch mal vernünftige Strings. C-Strings. > Sag's anders herum: Dort, wo man moderne Dinge wie GUI's benötigt - also > überall auf allen PC's dieser Welt einschließlich aller Smartphones, > Tablets, Navis - kann man C nicht wirklich einsetzen Korrekt. Ich habe GUI-Programmierung unter Xwindow in reinem C gemacht, das ist zum Abgewöhnen. Dafür nimmt man sinnigerweise Frameworks, wenn man in endlicher Zeit fertigwerden will. > Also bleibt noch die Welt der Kommandozeile Und Mikrocontroller. Was für ein Zufall, daß diese Webseite hier ausgerechnet mikrocontroller.net heißt. ;-) > gröhl... mal im Ernst: was soll das bitte? Wenn Du keine Fehlerbehandlung machen willst, bitte. Dann brauchst Du sie vielleicht. Ich komme noch aus einer Zeit, wo sämtliche Inputs vor der Verarbeitung zu validieren waren. > Jetzt übertreibst du es aber gar zu sehr. C kennt keine Strings. Punkt. Pascal auch nicht. Strings sind in nem Header definiert als array of char - und alle mit derselben Länge wegen des dämlichen Typensystems. > Wie oft dort wieder und wieder jede blöde Zeichenkette nach > diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf > intelligentere Weise zu merken, ist grauenvoll. Ach was. Und in Pascalstrings kannste einen Texteditor dann viel effizienter bauen - außer natürlich, Dein Text sollte mehr als 256 Zeichen haben. Fasse Dich kurz! Außerdem ist das kein Defizit von C, sondern der Programmierer. In so einer Anwendung macht man das auch nicht mit immer neuem strlen. > Ja. Sehe ich auch so. Aber man muß es ergänzen mit "Und wo ist eine > High-Level-Sprache, die man eben für höhere Level benutzen kann? Und die > so nebenbei den Bereich von C auch mit abdeckt?" C++ ist es jedenfalls nicht. Also wenn man so eine Konstellation hat, würde ich eher für die Speedkracher auf C setzen und das dann etwa aus Python heraus interfacen. Mit Python hat man dann auch den wesentlichen Produktivitätsfaktor, der keineswegs OOP ist (das ist ein Mythos), sondern vielmehr automatisches Speichermanagement.
W.S. schrieb: > Low Level war früher, da wurde jedes Kilobyte an RAM mit Gold > aufgewogen. > > Heutzutage braucht man was Anderes, nämlich Programmiersprachen, die: > > - moderne Programmelemente (GUI) und Beherrschung größerer Datenelemente > (Objekte und Kapselung) besser machen als C Einen XLP PIC12F möchte ich aber doch lieber in C Programmieren geht schneller als in Assembler, und die Baterie sollte doch einige Jahre halten. Für das was du willst gibt es ja schon lange C++ ;)
mec schrieb: > Einen XLP PIC12F möchte ich aber doch lieber in C Programmieren geht > schneller als in Assembler, und die Baterie sollte doch einige Jahre > halten. Für das was du willst gibt es ja schon lange C++ ;) Bügelt auch weniger Falten aus dem Hirn :) Aber nur OHNE XC Compiler in der Free Version!
W.S. schrieb: >> Falsch, C99 beispielsweise hat auch portable Datentypen eingeführt. > > O jemine, schon wieder dieser unselige Krempel. Da hat überhaupt keiner > irgendwas eingeführt, sondern es war die finale Kapitulation. Und zwar > in der Form, daß man gesagt hat "Leute macht euch für eure partikuläre > Architektur eine Headerdatei, wo ihr reinschreibt typedef unsigned long > uint32_t; und so weiter. Falsch! > Sowas haben Legionen von Leuten zuvor schon längst gemacht mit u32 oder > anderen selbstausgedachten Namen. Jedem C-Compiler ist das völlig > schnurz. Er kennt all dieses Zeugs nur dann, wenn man ihm so eine > Headerdatei zuvor in den Rachen geworfen hat. Falsch! > Sowas kann jeder, du könntest dir auf diese Weise auch nop32_t oder > T32NOP oder sonstwas kreieren. Es ist eben Mumpitz, den jeder für sich > machen kann und es ist NICHT eine tatsächliche Sprachänderung. Kapiere > das mal. Kapiere du doch bitte mal, dass das zwar nicht im Sprachkern enthalten ist, aber sehr wohl in der ISO-Norm, die die Sprache beschriebt. Jeder C99-konforme Compiler muss diesen Header mitbringen, mit genau den Typnamen, wie sie in der ISO-Norm vorgegeben sind. Die Idee ist gerade die, dass nicht mehr jeder die Typen selber mit eigenen Namen definieren muss, sondern diese einheitlich sind. Warum die Typen nicht als Schlüsselwörter im Sprachkern eingebaut worden sind, hab ich oben schon mal erklärt. Du hattest im Gegenzung natürlich wie immer mal wieder keine Begründung, warum es anders gelöst sein sollte, wiederholst aber regelmäßig lautstark, für wie furchtbar du es hältst. Offenbar gehört für dich die gesamte Standardbibliothek, die sehr wohl als Teil der Sprache zu sehen ist, nicht zu dieser. Was in der Standardbibliothek enthalten sein muss, ist genaus festgelegt, wie der Rest. > Ich sagte es ja schon: die Gründe für C sehe ich vorrangig im > außertechnischen Bereich. Was auch immer das bedeuten soll. Ich wüßte jetzt nicht, welches "außertechnische" System man in C programmieren könnte. >> In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams >> nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende >> Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze. > > Sag's anders herum: Dort, wo man moderne Dinge wie GUI's benötigt - also > überall auf allen PC's dieser Welt einschließlich aller Smartphones, > Tablets, Navis - kann man C nicht wirklich einsetzen, denn dafür ist es > zu poplig. Und doch werkelt in all diesen Geräten eine ganze Menge C-Code. In der Regel nicht auf der GUI, aber im Kernel, Treibern und vielen Bibliotheken. Denn auch wenn du es nicht glauben magst: Obwohl man von der Software nur die GUI sieht, ist die bei weitem nicht das einzige, woraus sie besteht. >> Strings gehen in C als C-Strings tadellos. Man kann sogar Pascalstrings >> nachbilden, falls man das wollen sollte. Natürlich gibt die Sprache das >> her. > > Jetzt übertreibst du es aber gar zu sehr. C kennt keine Strings. Punkt. C hat keinen eigenen Datentyp für Strings. Das heißt nicht, dass es sie nicht kennt. Stringhandling ist aber wirklich nicht der glorreichste Teil von C.
W.S. schrieb: > Wie oft dort wieder und wieder jede blöde Zeichenkette nach > diesem abgesucht wird (strlen), Ja, das wird von Anfänger oft falsch gemacht. Wann braucht man denn vor der Verarbeitung des Strings die Länge? Beim besorgen von Speicher für eine Kopie und beim Anhängen (strcat). In den anderen Fällen kannst du bei der Bearbeitung auf den Stringterminator achten.
Das größte Problem von C ist, dass auch in der Standard Library zuwenig auf Buffer Overflows geachtet wird. Man hätte schon 1989 alle betroffenen Stringfunktionen so erweitern müssen, dass die Größe des Zielbereichs mit angegeben wird.
Jörg W. schrieb: > Ja, vermutlich schon. Es gab ja auch mal Ansätze für eine Portierung > von GNU Ada auf den AVR, aber so wirklich weit gekommen waren sie > wohl auch nicht. Wie muss man sich so eine Portierung eigentlich vorstellen? Ich meine mich zu erinnern dass der gcc ja mehrere Zwischenkompilate erzeugt, Bytecode (GIMPL?) usw. Ein Ada-Frontend existiert ja (GNAT). Ein AVR-Backend auch (als Teil des avr-gcc). Ich dachte bisher, das Frontend würde einfach plattformunabhängigen Bytecode produzieren. Der Teil des gcc, der dann letzlich Assemblercode für AVR produziert hat ja eigentlich keine Berührungspunkte mehr zur ursprünglichen Sprache, dem stört es doch nicht ob das mal C oder Ada war. Oder ist das alles nicht so sauber getrennt wie ich mir das vorstelle?
:
Bearbeitet durch User
Dirk B. schrieb: > Das größte Problem von C ist, dass auch in der Standard Library zuwenig > auf Buffer Overflows geachtet wird. > > Man hätte schon 1989 alle betroffenen Stringfunktionen so erweitern > müssen, dass die Größe des Zielbereichs mit angegeben wird. Dafür gibt es ja C++ ;)
Dirk B. schrieb: > Man hätte schon 1989 alle betroffenen Stringfunktionen so erweitern > müssen, dass die Größe des Zielbereichs mit angegeben wird. strcpy, strcat, sprintf etc. haben allesamt Äquivalente mit Größenangabe; die "ollen Kamellen" musste man schon 1989 nicht mehr. Rausschmeißen aber ging nicht, weil anders als bei akademischen Lehrsprachen die Wart- und Weiterverwendbarkeit von existierendem Code bei C nicht unwichtig ist. Akademische Lehrsprachen können sich leisten, allen bisher geschriebenen Code wegzuwerfen (ist ja eh' nur dazu da, zu Lehrzwecken geschrieben zu werden), Sprachen, die in einem produktiven Kontext eingesetzt werden, können das nicht. Unbestritten: C vor C89 war eklig, widerwärtig und bäh. Aber es gibt (resp. gab) auch vor 1989 schon in C geschriebene erhaltenswerte Software, die aufgrund ihres Codeumfanges in "reines" C89 umzuschreiben ein Wahnwitz gewesen wäre, zumal in der Übergangszeit durchaus auch noch Mischbetrieb möglich sein musste (der gleiche Code musste auf System A und System B verwendbar sein, für System A gab es einen C89-Compiler, aber für System B nicht). Und im Produktiveinsatz ist oft einfach nicht die Zeit vorhanden, um erpropt funktionierenden Code nur wegen eines neuen Sprachstandards zu überarbeiten. Freunde akademischer Lehrsprachen ist so eine Problemstellung natürlich völlig schnuppe.
Rufus Τ. F. schrieb: > Software, die aufgrund ihres Codeumfanges in "reines" C89 umzuschreiben > ein Wahnwitz gewesen wäre, Wie etwa Unix und die üblichen Systemprogramme, Compiler, ...
:
Bearbeitet durch User
Le X. schrieb: > Ich meine mich zu erinnern dass der gcc ja mehrere Zwischenkompilate > erzeugt, Bytecode (GIMPL?) usw. Er produziert direkt Assembler. Intern gibt es Zwischencodestadien, aber das spielt nach aussen hin keine Rolle. > Ich dachte bisher, das Frontend würde einfach plattformunabhängigen > Bytecode produzieren. Intern wird über abstrakte Zwischenstufen wie Baumdarstellungen (GENERIC, GIMPLE) ein schon eher an Maschinen erinnernder Zwischencode RTL (Register Transfer Language) erzeugt. In diesen Teilen finden die meisten Optimierungen statt. Danach wird die RTL in den Assembler-Code der Zielmaschine umgesetzt. Dieser Zwischencode ist aber normalerweise eine rein programminterne Darstellung, d.h. er taucht nicht einer externalisierten Form auf, wie es etwa Bytecode wäre. > Der Teil des gcc, der dann letzlich Assemblercode > für AVR produziert hat ja eigentlich keine Berührungspunkte mehr zur > ursprünglichen Sprache, dem stört es doch nicht ob das mal C oder Ada > war. Im Prinzip ja. Allerdings müssen sich für neue Frontends alle Elemente der Quellsprache brauchbar auf den Zwischencode abbilden lassen. So gäbe es beispielsweise ohne eine Zwischencodedarstellung des Operators ?: sicherlich Problem mit der Umsetzung von C/C++.
:
Bearbeitet durch User
A. K. schrieb: > Wie etwa Unix und die üblichen Systemprogramme, Compiler, ... Naja, in den vergangenen 25 Jahren wird da schon etliches überarbeitet worden sein, so daß man in den aktiven Teilen davon jetzt kaum noch auf alten K&R-Code treffen dürfte.
W.S. schrieb: > Anmerkung zur Effizienz: Es ist geradezu grauselig, was für einen > unnötigen Ressourcenverbrauch das unselige Nullbyte verursacht. Man > schaue mal in ein x-beliebiges C-Programm hinein, das mit irgendwelchem > Text umgeht. Wie oft dort wieder und wieder jede blöde Zeichenkette nach > diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf > intelligentere Weise zu merken, ist grauenvoll. Was hindert Dich daran, eigene effizientere String-Funktionen zu schreiben?
Rufus Τ. F. schrieb: > Naja, in den vergangenen 25 Jahren wird da schon etliches überarbeitet > worden sein, so daß man in den aktiven Teilen davon jetzt kaum noch > auf alten K&R-Code treffen dürfte. Klar. Aber bei mir auf der Platte finde ich noch K&R Code. ;-)
:
Bearbeitet durch User
Rufus Τ. F. schrieb: > Rausschmeißen aber ging nicht, weil anders als bei akademischen > Lehrsprachen die Wart- und Weiterverwendbarkeit von existierendem Code > bei C nicht unwichtig ist. Dieser Meinung bin ich nicht, auch wenn stark vertreten in der Programmiergemeinde. Bei jeder Version (C89, C99, C11...) hätte man die "gefährlichen" Funktionen rausschmeissen müssen und bessere integrieren. Dies hätte dazu geführt, dass ein saubererer Programmierstil entwickelt worden wäre, statt sich an den alten Funktionen festzuhalten, ganz im Sinne von: Sie funktionieren ja noch. Nur um diesen paar Funktionen wegen, muss man aber auch nicht gleich eine gesamte neue Sprache erschaffen. Wenn man als Analogie unsere gesprochenen Sprachen nimmt, so werden auch schreibweisen obsolet und später schlicht falsch, wenn man sie weiterhin wie vor zig Jahren schreibt. 99% der Sprache bleiben aber erhalten. Was die Wiederverwendbarkeit angeht: Das wäre sogar heute möglich, ohne dass die Sprache einen Bruch erlitten hätte - compilerswitches. Wenn ein Programm in C89 geschrieben wurde, muss man es nicht nach C99 portieren. Man kann, aber das ist dann mit etwas Arbeit verbunden. Und wenn man nicht möchte, dann programmiert man auch in 2016 noch in C89. C++14 hat diesen Schritt nicht gescheut und std::gets gestrichen. Wer diese Funktion weiterhin benutzen möchte, programmiert nach wie vor in C++03 oder C++11 und wird nicht zum "upgrade" gezwungen.
Operator S. schrieb: > Dieser Meinung bin ich nicht, auch wenn stark vertreten in der > Programmiergemeinde. Bei jeder Version (C89, C99, C11...) hätte man die > "gefährlichen" Funktionen rausschmeissen müssen und bessere integrieren. Dann wäre der Standard ignoriert worden und die Compilerbauer hätten den alten Kram auf eigene Rechnung drin gelassen, mindestens als Option. Die normative Kraft des Faktischen schlägt Ideologie.
W.S. schrieb: > Anmerkung zur Effizienz: Es ist geradezu grauselig, was für einen > unnötigen Ressourcenverbrauch das unselige Nullbyte verursacht. Man > schaue mal in ein x-beliebiges C-Programm hinein, das mit irgendwelchem > Text umgeht. Wie oft dort wieder und wieder jede blöde Zeichenkette nach > diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf > intelligentere Weise zu merken, ist grauenvoll. Au weia. Soll es jetzt besser sein zu jedem 3 Byte langen String 4 bzw. 8Byte Länge vorzuhalten? Untersucht mal eure Programme! 90% der Strings sind für Fehlermeldungen und noch dazu konstant (beim µC im Flash). Eine 0 am Ende ist die kürzeste Form den String darzustellen. Und ja mich nervt das auch mächtig wenn ich die Fehlermeldungen wegen dem schnarchlangsamen strlen() 10nS später zu sehen bekomme... Jedes richtige Programm das mit Text umgeht muss sich den ja irgendwo dynamisch Speichern. Wie und wo das passiert möchte aber immer noch ich entscheiden und nicht so ein bekloppter Pascal-Erfinder. Nur gut dass es schon zur Zeit als C erfunden wurde Leute gab die wussten um was es geht. Die 0 am Ende eines Strings als unsegliche Resourcenverschwendung zu bezeichnen ist einfach nur lächerlich. Ich wage mal eine Aussage und lasse mich auch gern von was anderem Überzeugen: Fast alles ausser C(C++) was man heute so als Hochsprache bezeichnet ist in C(C++) entwickelt worden. Und deren String-Implementierungen haben zusätzlich zur mitgeschleppten Länge auch noch eine 0 (oder 2 bei Unicode) am Ende. Jedenfalls ist das bei JAVA, JavaScript und Php so. Hätten die Entwickler doch lieber mal W.S. gefragt...
Operator S. schrieb: > Dies hätte dazu geführt, dass ein saubererer Programmierstil entwickelt > worden wäre, statt sich an den alten Funktionen festzuhalten, ganz im > Sinne von C ist keine Lehrsprache, wie schon geschrieben wurde. Die Philosophie von C ist, daß der Programmierer verantwortlich ist. C ist nicht fürs Pascal-hafte Händchenhalten. Deswegen war es klar, daß man die Programmierer nicht zu ihrem vermeintlichen Besten zwingen würde. Zweitens wäre es bei den Stringfunktionen strcpy/strcat sinnlos, sie zu streichen, um die Leute zu zwingen. Es sind Dreizeiler, die man mit Leichtigkeit selber schreiben kann. Drittens setze ich gelegentlich diese älteren Funktionen auch heute noch ein. Nämlich dann, wenn ich die Inputs bereits vorher validiert habe und auf Geschwindigkeit optimieren will. Oder wenn es um Strings geht, die das Programm nicht von außen empfangen hat, sondern selber generiert hat. Strcpy ist nämlich nicht per se gefährlich, sondern nur dann, wenn man die Länge des src-Strings nicht kennt und daher nicht weiß, ob das in den dst-Buffer paßt.
temp schrieb: > Eine > 0 am Ende ist die kürzeste Form den String darzustellen. WS wollte hier wohl kaum auf den Speicherverbrauch hinaus, der bei Pascalstrings ja genauso hoch ist - Byte 0 ist beim Pascalstring ja dessen Länge. Worum es ging, ist Ressourcenverbrauch im Sinne von verschwendeter CPU-Zeit. Und ja, wenn man sich mit C-Strings blöd anstellt, dann kann man damit O(n^2)-Sachen fabrizieren, die sich aber im Quelltext als O(n) tarnen, das stimmt. Wenn man sich nicht blöd anstellt, existiert dieses Problem aber nicht. Andererseits kann man auch in Pascal große Datenmengen mit einem Bubblesort sortieren, ohne daß man das jetzt der Sprache vorwerfen würde. Und außerdem wird man bei längeren Texten, wo man überhaupt solche strlen-Probleme hat, auch in Pascal letztlich auf ein größeres char-Array zurückgreifen, weil Pascalstrings für die Länge nur ein Byte haben, also 255 Zeichen zulassen.
Le X. schrieb: > Oder ist das alles nicht so sauber getrennt wie ich mir das vorstelle? In der Praxis hast du auf jeden Fall irgendwelche Wechselwirkungen. Soweit ich verstanden habe, kommt bei Ada noch hinzu, dass im Sprachumfang sehr viel mehr an Hintergrund-Bibliothek festgeschrieben ist (bis hin zu Multitasking) als bei C, sodass eine Implementierung, bevor sie sich „komplett“ nennen darf, sehr viel mehr Arbeit hat. Allerdings ist auch AVR-GCC/avr-libc nicht strikt konform mit dem C-Standard. Das fängt an mit zu kleinen double-Datentypen (ein Byte mehr hätte genügt für Konformität, wäre aber ansonsten ein im GCC völlig unüblicher Datentyp, und 64 bit wollte man wohl damals lieber nicht dafür abstellen), aber auch einige Teile der Bibliothek fehlen, die vom Standard vorgeschrieben wären: wchar gibt's gar nicht, aber auch sonst fehlt hie und da mal was, weil's auf einem Controller nicht so viel Sinn hat. Ist letztlich ein offensichtlich einigermaßen brauchbarer Kompromiss, der für die meisten Nutzer nahe genug am C-Standard ist, als dass er von ihnen angenommen worden ist.
> Bei jeder Version hätte man die > "gefährlichen" Funktionen rausschmeissen müssen Das hat man nicht einmal bei Java gemacht. Ich kenne kein einziges deprecated Java Feature, das tatsächlich entfernt wurde. Wenn das schon bei Java (der "wir machen alles besser" Sprache) nicht gemacht wurde, dann bei C erst Recht nicht. Es wird gute Gründe dafür geben, die nicht jedem hier ersichtlich sind. Einige wurden ja schon genannt. C ist ganz sicher in vielerlei Hinsicht nicht ideal. Die Sprache wird nicht mehr weiter entwickelt. Man muss sie daher so nehmen, wie sie ist, oder man nimmt was anderes. Über ihre Unzulänglichkeiten zu diskutieren ist völlig unsinnig. Wir könnten hier genau so gut über die deutsche Sprache diskutieren. Das wäre ebenso Sinnlos. Jeder der hier von der Arbeit mit C abraten tut, sollte auch vom deutsch-Sprechen abraten. Und jeder, der meint, er müsse die Sprache verteidigen, kann ja mal versuchen, den Franzosen deutsch nahezulegen. Völlig Sinnlos ist das!
Rolf M. schrieb: > Stringhandling ist aber wirklich nicht der glorreichste > Teil von C. Was glorreich auch immer heißen mag, aber ich arbeite sehr viel mit Strings und ich kenne keine Sprache, die da mehr ermöglicht als C. Eine Menge zu kritisieren hab ich nur an Library-Funktionen. Zum Bleistift dass strcpy(), strcat() und Verwandte den Stringanfang zurückgeben, der ja eh schon bekannt ist und als Argument übergeben wird, anstatt den viel informativeren Zeiger auf das Stringende. Vermutlich ein Kompromiss wegen dem vielen Unverständnis, das Anhänger von Lehrsprachen dem Programmieren mit Zeigern entgegenbringen. Unverständlich ist mir auch die Rückgabe von NULL in Funktionen wie strchr(), wenn kein Zeichen gefunden wurde. Auch hier wäre ein Zeiger auf das Nullzeichen am Ende praktischer, denn das wäre zwar ein leerer, aber gültiger String, während NULL zwingend eine Extrabehandlung erfordert. Aber das sind keine Mängel der Sprache oder String-Konvention, sondern der Library. Niemand zwingt mich, sie zu verwenden, ich kann mir eigene schreiben, die meinen Ansprüchen genügen.
Jobst Q. schrieb: > kenne keine Sprache, die da mehr ermöglicht als C. Naja, Python oder Perl könnte ich dir da sofort nennen. :)
Jobst Q. schrieb: > Was glorreich auch immer heißen mag, aber ich arbeite sehr viel mit > Strings und ich kenne keine Sprache, die da mehr ermöglicht als C. Sie ermöglicht auch, sich selbst ins Knie zu schiessen. Das kann man gut finden, weil man das als perfekter Programmierer natürlich nicht tut. Oder schlecht, weil man das als normaler Programmierer manchmal doch tut. Was passieren kann, wenn man bei der Längenberechnung in einem speziellen Fall auch nur um ein einziges Byte daneben liegt, kann man sehr schön hier lesen: https://daniel.haxx.se/blog/2016/10/14/a-single-byte-write-opened-a-root-execution-exploit/ Aber das passiert den hiesigen Programmierern selbstverständlich nie.
:
Bearbeitet durch User
Jobst Q. schrieb: > Rolf M. schrieb: >> Stringhandling ist aber wirklich nicht der glorreichste >> Teil von C. > > Was glorreich auch immer heißen mag, Damit meinte ich, dass Stringhandling sehr mühsam und fehlerträchtig ist im Vergleich zu anderen Sprachen. Klar hat man dafür mehr in der Hand und kann auf µCs sehr viel besser mit dem begrenzten Speicher und dessen Aufteilung in RAM und Flash umgehen. Aber auf dem PC tue ich mir nicht ausgedehnte Arbeiten mit Strings in C an. Da nehme ich lieber Python oder C++ mit Qt oder so. > aber ich arbeite sehr viel mit Strings und ich kenne keine Sprache, die > da mehr ermöglicht als C. C bringt ja noch nicht mal reguläre Ausdrücke mit. > Eine Menge zu kritisieren hab ich nur an Library-Funktionen. Was ist denn für dich das Stringhandling von C, wenn nicht die Library-Funktionen? Im Sprachkern ist ja wirklich nichts dafür enthalten. Gut, man kann noch alles Zeichen für Zeichen von Hand behandeln, aber dann baut man auch nur die Library-Funktionen nach. > Unverständlich ist mir auch die Rückgabe von NULL in Funktionen wie > strchr(), wenn kein Zeichen gefunden wurde. Auch hier wäre ein Zeiger > auf das Nullzeichen am Ende praktischer, denn das wäre zwar ein leerer, > aber gültiger String, während NULL zwingend eine Extrabehandlung > erfordert. Die braucht man doch sowieso. Ich suche ein Zeichen, und wenn es nicht gefunden wird, muss ich diesen Fall eh separat behandeln. Im übrigen kann man mit strchr auch explizit nach dem \0 selbst suchen. Ob man das braucht, sei mal dahingestellt, aber es ginge nicht, wenn dessen Adresse auch dann zurückgegeben würde, wenn das gesuchte Zeichen gar nicht gefunden wird.
Operator S. schrieb: > Bei jeder Version (C89, C99, C11...) hätte man die "gefährlichen" > Funktionen rausschmeissen müssen und bessere integrieren. Die meisten der oft als "gefährlich" genrandmarkten Funktionen sind ja nicht grundsätzlich gefährlich. In vielen Kontexten können sie unbedenklich eingesetzt werden, nur eben nicht in allen. Da es für die gefährlichen Anwendungsfälle teilweise keine sinnvolle Alternativfunktionen gab, wurde diese nachträglich hinzugefügt. Das heißt aber nicht, dass die Originalfunktionen deswegen obsolet sind. Die einzige Ausnahme stellt gets dar. Diese Funktion ist fast immer gefährlich und wurde deswegen – ganz deinem Wunsch entsprechend – in C11 rausgeschmissen.
Jörg W. schrieb: > Jobst Q. schrieb: >> kenne keine Sprache, die da mehr ermöglicht als C. > > Naja, Python oder Perl könnte ich dir da sofort nennen. :) Das ist eine andere Ebene. Da hat man eine umfangreichere Library, ist für viele bequemer, die lieber Referenzbücher studieren, als sich die einfachen Grundlagen der Zeigerprogrammierung anzueignen. Was in C möglich ist, zeigt sich bei Problemen, die nicht zu den Standardaufgaben gehören, die von den Library-Entwicklern berücksichtigt wurden. Der Unterschied zwischen Highlevel-Sprachen und C ist wie zwischen LEGO-Baukasten und Werkzeugkasten. Sicher kann man mit LEGO schneller ein Haus bauen, aber vom Hausbau hat man dadurch wenig begriffen.
A. K. schrieb: > Was passieren kann, wenn man bei der Längenberechnung in einem > speziellen Fall auch nur um ein einziges Byte daneben liegt, kann man > sehr schön hier lesen Nur hat das mit C-Strings nichts zu tun, weil der Berechnungsfehler mit einem escape'ten Punkt am Ende zu tun hatte. Mit anderen Worten, das lag am StringINHALT und wäre bei jeder anderen Implementation von Strings ebenfalls passiert.
In c muss man nicht so viel konkretes Wissen über 'howto' haben. Man muss einige Sachen verstanden haben und damit kann man sich dann extrem viel ausdenken. Also auch ohne auf externe libraries zurückzugreifen. Oben genanntes Python ist da ja grundverschieden. Da muss man dann genau wissen, was vom immensen Umfang geboten wird und wie das geht. Das meint Jobst vermutlich mit "Referenzbücher studieren". Das ist auch gar nicht von der Hand zu weisen. Wertfrei und ohne dass ich jetzt das eine oder andere präferieren würde. Von meiner Neigung her finde ich dann c angenehmer, eben wegen des größeren Freiheitsgrades. Python oder allgemein komplexe Sprachen geht man heutzutage aber wahrscheinlich so an, dass man sein Problem in Google tippt und das Codestück was ausgespuckt wird dann kopiert. Ist bei meinen .net Exkursionen eigentlich auch so gelaufen. Von sich alleine heraus ausdenken kann man sich halt weniger. Das sind aber auch von der Ausrichtung der Sprachen irgendwie Äpfel und Birnen...
Yalu X. schrieb: > Da es für die gefährlichen Anwendungsfälle teilweise keine sinnvolle > Alternativfunktionen gab, wurde diese nachträglich hinzugefügt. Das > heißt aber nicht, dass die Originalfunktionen deswegen obsolet sind. hm, komisch. wenn ich sprintf verwenden will, sagt mein compiler (VC)genau das. Er bemeckert, dass die Funktion deprecated ist.
Nop schrieb: > Nur hat das mit C-Strings nichts zu tun, weil der Berechnungsfehler mit > einem escape'ten Punkt am Ende zu tun hatte. Mit anderen Worten, das lag > am StringINHALT und wäre bei jeder anderen Implementation von Strings > ebenfalls passiert. Der Rechenfehler wäre auch passiert. Aber das Programm hätte das Ende des allozierten Speichers nicht überschrieben und wäre wahlweise abgekackt oder hätte im Ziel das letzte Byte weggelassen und dann nicht richtig funktioniert. Es wäre aber kein root exploit draus geworden.
Konstantin F. schrieb: > Python oder allgemein komplexe Sprachen geht man heutzutage aber > wahrscheinlich so an, dass man sein Problem in Google tippt und das > Codestück was ausgespuckt wird dann kopiert. Nee, für Python trifft das ganz gewiss nicht so zu. nicht"Gast" schrieb: > wenn ich sprintf verwenden will, sagt mein compiler (VC)genau das. Er > bemeckert, dass die Funktion deprecated ist. Visual C und aktuelle C-Standards sind doch ohnehin unversöhnliche Gegensätze.
:
Bearbeitet durch Moderator
nicht"Gast" schrieb: > hm, komisch. wenn ich sprintf verwenden will, sagt mein compiler > (VC)genau das. Er bemeckert, dass die Funktion deprecated ist. Warnung 4996. Damit hat MS aber übertrieben, weil die bei auch bei Funktionen ausgespuckt wird, die eine Längenangabe haben (wie z.B. strncpy).
A. K. schrieb: > Der Rechenfehler wäre auch passiert. Aber das Programm hätte das Ende > des allozierten Speichers nicht überschrieben Nachgehakt hätte das sprachbedingtes, automatisches Bounds-Checking bedeutet. Für jeden Zugriff und überall. Aber: nur weil man davon im Sourcetext nichts sieht, heißt das nicht, daß das kostenlos zu haben wäre. Deswegen hat C das ja auch nicht, weil: keine Compilermagic hinter dem Rücken des Programmierers. Eine Vorstellung, was das für die Performance bedeutet, kann ja ein Testlauf unter Valgrind geben.
.. bzw, man kann natürlich auch in C die Zugriffe kapseln und Grenzen checken. Daß das hier nicht gemacht wurde, ist aber keine Einschränkung von C gewesen, sondern eine Wahl des Programmierers.
Nop schrieb: > Nachgehakt hätte das sprachbedingtes, automatisches Bounds-Checking > bedeutet. Für jeden Zugriff und überall. Aber: nur weil man davon im > Sourcetext nichts sieht, heißt das nicht, daß das kostenlos zu haben > wäre. Korrekt. Aber angesichts der Häufigkeit, wie der mittlerweile Sicherheitsprobleme durch buffer overflows auftreten, fände ich etwas mehr CPU für diesen Zweck eine sinnvolle Investition.
Nop schrieb: > .. bzw, man kann natürlich auch in C die Zugriffe kapseln und Grenzen > checken. Daß das hier nicht gemacht wurde, ist aber keine Einschränkung > von C gewesen, sondern eine Wahl des Programmierers. Das ist - etwas überspitzt formuliert - der Unterschied zwischen Assembler und Hochsprache. Man kann alles auch in Assembler machen, aber es wird halt etwas umständlicher. Der Sinn von Hochsprachen liegt darin, nicht alles selber machen zu müssen.
:
Bearbeitet durch User
A. K. schrieb: > Aber angesichts der Häufigkeit, wie der mittlerweile Sicherheitsprobleme > durch buffer overflows auftreten, fände ich etwas mehr CPU für diesen > Zweck eine sinnvolle Investition. Ich fände etwas mehr Investition in die Ausbildung der Programmierer und in ihre Gehälter sinnvoller - nicht jeder, der mal HTML "programmiert" hat und mit etwas Javascript zurechtkam, ist geeignet, auf Werkzeuge wie C losgelassen zu werden. Ja, es gibt Bücher mit Titeln wie "C in 21 Tagen", aber die sind ähnlich ernstzunehmen wie Bücher mit Titen wie "21 kg in 21 Tagen abnehmen" ...
Rufus Τ. F. schrieb: > Ich fände etwas mehr Investition in die Ausbildung der Programmierer Man sollte das Eine tun, ohne das Andere zu lassen. > und in ihre Gehälter sinnvoller Mehr Gehalt macht einen Programmierer zunächst nur teurer, nicht besser. Ok, es ist schon was dran. Aber wenn man gute Leute rausekelt, weil sie beispielsweise aufgrund von realistischen Einschätzungen von den Träumern ringsum bloss als Hemmschuh gesehen werden, dann hilft auch kein Geld.
:
Bearbeitet durch User
A. K. schrieb: > Mehr Gehalt macht einen Programmierer zunächst nur teurer, nicht besser. Äh, andersrum. Nur wenn man bereit ist, einen Programmierer angemessen zu bezahlen, bekommt man einen Programmierer, der nicht billig ist. Wer nur Berufsanfängergehälter zahlt, bekommt auch nur Berufsanfänger bzw. Berufsanfängerengagement.
Gib dem gleichen Programmierer mehr Geld und er wird besser?
:
Bearbeitet durch User
A. K. schrieb: > Gib dem gleichen Programmierer mehr Geld und er wird besser? Das sollte ich meinem Chef mal als lohnenswerten Versuch vorschlagen :D (Das war Spaß. Bei meiner Arbeit programmiere ich nicht.)
A. K. schrieb: > Gib dem gleichen Programmierer mehr Geld und er wird besser? You get what you pay for. If you pay peanuts you get monkeys.
Dirk B. schrieb: >> Wie oft dort wieder und wieder jede blöde Zeichenkette nach >> diesem abgesucht wird (strlen), > > Ja, das wird von Anfänger oft falsch gemacht. > > Wann braucht man denn vor der Verarbeitung des Strings die Länge? > Beim besorgen von Speicher für eine Kopie und beim Anhängen (strcat). > > In den anderen Fällen kannst du bei der Bearbeitung auf den > Stringterminator achten. ICH?? Was, ich? Junge, mir ist es langsam leid. Guck nur ein einziges Mal in die Bibliotheksfunktionen von C - falls dir der zugehörige Quellcode zur Verfügung steht. Dort findest du bei jeder Stringfunktion ein oder mehrmaliges Aufrufen von strlen. Bevor du also hier von Anfängern schwafelst, solltest du dich besser zuvor mal richtig informieren. Der Punkt ist, daß irgendwelche sogenannten Stringfunktionen eben keinen tatsächlichen Stringtyp ersetzen können. Sowas muß in die Sprachdefinition eingebaut sein und der Compiler muß das selber handhaben - SELBER! verstehst du das? Die Basis dafür ist, daß man ein sinnvolleres Stringformat bräuchte, wo das allgegenwärtige Abklappern der Zeichen einfach nicht nötig ist. Sowas kann kein Compiler-Benutzer sich selber schreiben, sowas muß in den Compiler eingebaut werden. Im übrigen gilt das in entsprechender Form auch für die albernen uint32_t Masche. Solange der Compiler SELBST keine anderen Datentypen kennt als int mit den Geschmacksrichtungen long, short, unsigned, signed, so lange ist das Zusammenschreiben irgendwelcher Headerdateien nichts als Brimborium und Scharlatanerie. Hier wird dem unerfahrenen Programmierer vorgegaukelt, er hätte was Neues, aber es ist nur ein neues Geschenkpapier drum gewickelt. -------- Nun.. ich habe mittlerweile zum Thema eine Theorie: C ist bekanntermaßen in weiten Teilen nicht logisch aufgebaut, es fehlen Basismittel wie z.B. ein Boolean-Datentyp und vieles mehr, also wird das per ordre de mufti erledigt. Das muß ein Schüler der C-Programmiersprache eben auswendig lernen. Er muß dazu sich eben dran gewöhnen, daß es an vielen Stellen in C "eben so ist wie es ist, basta!". Nun gewöhnt er sich halt daran, daß Dinge, die ihm zuvor unlogisch oder nicht erklärlich sind, eben so sind wie sie sind und er gewöhnt sich langsam aber sicher daran, seinen logischen Verstand in solchen Fällen nicht mehr zu gebrauchen, sondern kurzerhand das Angeordnete als gegeben und einen unumstößlichen Fakt zu verinnerlichen. Am Ende solch einer mentalen Umwandlung hat so ein Programmerer seinen logischen Verstand weitgehend an der Garderobe abgegeben. W.S.
Was die Logik angeht, da gab es tatsächlich einen Abstieg, der schon mit K&R C begann und mit C89 nicht besser wurde. Die Logik wohlgemerkt. Die Sprache wurde besser. Nur sind Logik und Brauchbarkeit nicht deckend. So ist die Syntax der Typdeklaration zwar ziemlich logisch, aber auch ziemlicher Mist. Manche lernen sie einfach auswendig, obwohl logisch, weil sie die Logik dahinter nicht verstehen.
:
Bearbeitet durch Moderator
Ich muß mich in meiner Theorie ein bissel korrigieren: Es ist bei der Gewöhnung an C nicht nur die Logik betroffen. Frank M. schrieb: > Was hindert Dich daran, eigene effizientere String-Funktionen zu > schreiben? Ich habe das nicht nötig. Ich benutze in solchen Fällen einfach eine bessere Programmiersprache als C. Eine, wo sowas eingebaut ist. Nop schrieb: > Die vollkommen kranke Stringlogik von Pascal will ich auch nicht Nun ja, deine Erfahrungen mit Pascal sehen ausgesprochen steinalt aus - das ist etwa so, als wenn du heutzutage über K&R-syntax räsonniertest. Jörg W. schrieb: >> Da reicht auch eine schmale Implementierung die auf das sbrk ganz >> verzichten kann. > > Ist ja nun aber nicht so, dass es die nicht gäbe. > > Ja, man könnte sich allemal technisch elegantere Lösungen wünschen, > bei denen der Linker bereits entscheiden kann, was im Hintergrund > tatsächlich an Konvertierungen benötigt wird. Tja Jörg, die Generalidee bei C war und ist es eben, möglichst garnichts an Funktionen in den Compiler einzubauen. Das war dunnemals wegen begrenzer Ressourcen auch sehr verständlich, führt aber zu sowas wie printf und Formatstrings und dem damit notwendigerweise verbundenen Textinterpreter für den Formatstring. Auf dem PC ist das zumeist wurscht, da hat man heutzutage genug Ressourcen, um die immanente Uneffizienz dieser Strategie ignorieren zu können. Auf einem kleinen µC sieht das anders aus. Da ist die Strategie von Pascal mit str und write als Pseudo-Prozeduren bedeutend besser: Erstens: nimmt der Compiler die völlig variable Latte an all den Parametern selbst auseinander und zerlegt sie in all das, was gebraucht wird, Zweitens: läßt er logischerweise all die Funktionen weg, die konkret nicht gebraucht werden Drittens kann er auch mit variablen Formatangaben zurechtkommen (also sowas wie write(A:9:3, B:y*3:y); Viertens braucht das Verfahren keinen Formatstring und keinen zugehörigen Interpreter, weil der Compiler das alles zur Übersetzungszeit erledigt und somit zur Laufzeit keine Übersetzungsarbeit mehr zu leisten ist. Der Nachteil wäre dann nur, daß man keine zur Laufzeit generierten Formatstrings haben kann. Im Prinzip wäre sowas auch in C spielend möglich - vorausgesetzt, man arbeitet es direkt in die Sprache und in den Compiler ein. Eine Realisierung per Bibliotheksfunktion kann es jedoch nicht geben, da der Unterschied eben zentral darin besteht, Übersetzungsarbeit entweder zur Übersetzungszeit oder zur Laufzeit zu leisten. Die Chance zu sowas sehe ich alledings zu null an. In C hat man es ja nicht mal geschafft, mit Integertypen aufzuräumen UND Zeichentypen (char) von numerischen Typen zu trennen. W.S.
W.S. schrieb: > Guck nur ein einziges Mal in die Bibliotheksfunktionen von C - falls > dir der zugehörige Quellcode zur Verfügung steht. Dort findest du bei > jeder Stringfunktion ein oder mehrmaliges Aufrufen von strlen. Wirklich bei JEDER? Hast du denn selber nachgeschaut? Ich habe gerade mal die AVR-Libc durchgegrept. Ergebnis: In der kompletten Bibliothek gibt es keine einzige Funktion, die strlen aufruft. strlen wird ausschließlich von User-Code aufgerufen, und dort auch nur recht selten.
Also ein neues Keyword write, das wie eine Funktion benutzt wird, aber eine ganz andere Parameterübergabe hat. Das wäre doch mal innovativ. (gefundene Ironie darf nach Belieben weiterverwendet werden) Es mag ja sein, daß sich nicht jedes C-Detail jedem erschließt, aber deshalb muß man doch eine Sprache nicht mit neuem, inkonsistenten Zeug überladen, nur um Ausgaben auf stdout (hat Pascal sowas) zu machen.
A. K. schrieb: > Nur sind Logik und Brauchbarkeit nicht deckend. Das ist allen verständnisvollen Programmierern völlig klar. Es geht ja auch nicht darum hier irgendwas zu verteufeln, sondern es geht darum, die Sache einfach nur nüchtern beim Namen zu nennen und dabei auch mal deren Grenzen aufzuzeigen. Der TO hat sich an for(;;) gestoßen - und zu Recht. Formal ist das nicht falsch, aber es ist unleserlich, denn wir sind Menschen und keine Maschinen. Genau deshalb ist sowas eben schlechter Stil, denn man könnte das Ziel auf einsichtigere Weise behandeln, ohne dadurch irgend etwas an Effizienz zu verlieren. Weiter oben hat jeman das Wort 'Müslifaktor' gebraucht ("aber wie ich schon meinte, den Müslifaktor bei Pascal finde ich unerträglich"). Ich halte das für eine kreuzgefährliche Grundeinstellung. Bieder und in einfach gehaltener Quelle zu schreiben und das Optimieren dem Compiler zu überlassen, ist also manchem unerträglich. Alles Hasardeure? Das ist übrigens ein grundlegendes Thema: Viele C-Programmierer glauben immer noch, sie könnten durch vigilantische Kunststücke beim Formulieren dessen, was sie bezweicken wollen, an Platz sparen und Effizienz gewinnen - oder sich wenigstens vor ihren Stallgefährten brüsten. Das ist heutzutagen nur noch dummer Käse, denn die Compiler sind weitgehend sehr viel besser geworden als in der blutigen Anfangszeit. Die früher eventuell gewesene Notwendigkeit, selbst etwas zum Optimieren beizutragen, ist heutzutage nur noch ein Beitrag zur Unleserlichkeit. Soviel zu Logik, Brauchbarkeit und dem, was die Leute draus machen. W.S.
:
Bearbeitet durch Moderator
Yalu X. schrieb: > In der kompletten Bibliothek gibt es keine einzige Funktion, die strlen > aufruft. Ähemm... dann verrate mir doch mal, wie strcat und Konsorten einen String an einen anderen dranhängen - per magischem Endpunktfinden? ;-) W.S.
W.S. schrieb: > Die Chance zu sowas sehe ich alledings zu null an. In C hat man es ja > nicht mal geschafft, mit Integertypen aufzuräumen UND Zeichentypen > (char) von numerischen Typen zu trennen. Eine derart verbreitete Sprache reformiert man unter Wahrung weitgehender Kompatibilität, oder man baut unter anderem Namen eine neue Sprache wie man sie gerne hätte. Der Versuch, per ideologischem Zwang alte häufig gebrauchte Zöpfe abzuschneiden, würde nicht akzeptiert, sondern würde nur den offiziellen Sprachstandard von der Realität abkoppeln. Eine Unterscheidung in zueinander nicht zuweisungskompatible Integer, Booleans und Chars ist in C nicht reinreformierbar. Die fehlende Unterscheidung ist eine Art Axiom von C, ob man es mag oder nicht. Es ändern zu wollen brächte eine neue inkompatible Sprache, die irgendwie an C erinnert und zwecks Verwirrung auch dummerweise so heisst. C dafür zu kritisieren, dass es C bleibt, ist also unredlich. Du musst C deshalb nicht mögen, aber die Axiome von C sind fixiert. NB: Von C abgeleitete Sprachen existieren. Eine davon heisst D.
:
Bearbeitet durch User
Rufus Τ. F. schrieb: > nicht"Gast" schrieb: >> hm, komisch. wenn ich sprintf verwenden will, sagt mein compiler >> (VC)genau das. Er bemeckert, dass die Funktion deprecated ist. > > > Warnung 4996. Damit hat MS aber übertrieben, weil die bei auch bei > Funktionen ausgespuckt wird, die eine Längenangabe haben (wie z.B. > strncpy). strncpy ist auch eine üble Funktion. Wenn die Grenze erreicht ist, wird die '\0' nicht mit abgespeichert.
Rolf Magnus schrieb: >> Eine Menge zu kritisieren hab ich nur an Library-Funktionen. > > Was ist denn für dich das Stringhandling von C, wenn nicht die > Library-Funktionen? Im Sprachkern ist ja wirklich nichts dafür > enthalten. Gut, man kann noch alles Zeichen für Zeichen von Hand > behandeln, aber dann baut man auch nur die Library-Funktionen nach. Stringhandling ist die Bearbeitung von Strings beim Lesen und Schreiben. Da der String in C nichts anderes ist als ein Zeiger auf den Anfang, kann man damit alles machen. Im Gegensatz zu Sprachen in denen festgelegt ist, was man damit machen kann und was nicht. C hat eine klare Trennung von Sprache und Librarys und das finde ich positiv. Man kann im Prinzip alle Funktionen selbst schreiben und hat damit den vollen Überblick, was im Programm geschieht. > >> Unverständlich ist mir auch die Rückgabe von NULL in Funktionen wie >> strchr(), wenn kein Zeichen gefunden wurde. Auch hier wäre ein Zeiger >> auf das Nullzeichen am Ende praktischer, denn das wäre zwar ein leerer, >> aber gültiger String, während NULL zwingend eine Extrabehandlung >> erfordert. > > Die braucht man doch sowieso. Ich suche ein Zeichen, und wenn es nicht > gefunden wird, muss ich diesen Fall eh separat behandeln. Nicht immer. ZB wenn man über den Punkt die Erweiterung eines Dateinamens sucht. Wenn kein Punkt dabei ist, hat er keine Erweiterung und der Leerstring ist korrekt. Wenn es eine Fehlerbehandlung braucht, kann man das mit *s genauso gut wie mit s==NULL erkennen. > Im übrigen > kann man mit strchr auch explizit nach dem \0 selbst suchen. Ob man das > braucht, sei mal dahingestellt, aber es ginge nicht, wenn dessen Adresse > auch dann zurückgegeben würde, wenn das gesuchte Zeichen gar nicht > gefunden wird. In C hat jeder String eine \0 und die wird auch von meiner Funktion gefunden.
> dann verrate mir doch mal, wie strcat und Konsorten einen > String an einen anderen dranhängen Ihr wollt jetzt nicht im ernst um solche Pillepalle Funktionen feilschen, oder?
W.S. schrieb: > Eine Realisierung per Bibliotheksfunktion kann es jedoch nicht geben, da > der Unterschied eben zentral darin besteht, Übersetzungsarbeit entweder_ > zur Übersetzungszeit _oder zur Laufzeit zu leisten. Yep, und damit bist du komplett festgenagelt auf die Ausgabekanäle, wie sie in den Sprachumfang gegossen worden sind. Das ist doch genau einer der Kritikpunkte an Pascal oben, dass man das, was der Compiler bei write[ln] macht, nicht im eigenen Code ebenfalls zur Verfügung hat. Alles, was als Ausgabekanal nicht bereits so ist, dass es von der Implementierung als "Datei" betrachtet würde, kann man damit vergessen. Ich habe die Argumentlisten von writeln nicht mehr gut genug im Kopf, aber ich glaube mich zu erinnern, dass es an die Variantenvielfalt von printf-Formatierung nichtmal ansatzweise herankam. Ehrlich: vor 15 Jahren habe ich noch irgendwo mal ein Controllerprojekt gehabt, bei dem der Controller so klein war, dass printf() nicht gepasst hat. Das war aber auch das letzte Mal, dass mir das passiert war, vermutlich ein AT90S8535 oder sowas, der aber ansonsten schon gut mit Gleitkomma vollgestopft war. Seither habe ich nie ein Problem gehabt, dass einem Controller die Ressourcen ausgerechnet wegen der Benutzung von printf() ausgegangen wären. (avr-libc bietet ja durchaus genügend Alternativen, wenn man kein printf() haben will oder kann.)
W.S. schrieb: > Der TO hat sich an for(;;) gestoßen - und zu Recht. > Formal ist das nicht falsch, aber es ist unleserlich, Ein lächerlicher Streit. Wird durch Wiederholung nicht besser. > Die früher eventuell gewesene Notwendigkeit, selbst etwas zum Optimieren > beizutragen, ist heutzutage nur noch ein Beitrag zur Unleserlichkeit. Korrekt.
Jörg W. schrieb: > Yep, und damit bist du komplett festgenagelt auf die Ausgabekanäle, > wie sie in den Sprachumfang gegossen worden sind. Sprachen mit in der Sprache selbst fest integrierten Ausgabemethoden dürften sämtlich aus der Zeit von Batch- oder Commandline-Programmierung stammen. In anderen Umgebungen sind diese Elemente weitgehend obsolet.
:
Bearbeitet durch User
W.S. schrieb: > Im übrigen gilt das in entsprechender Form auch für die albernen > uint32_t Masche. Das ist keine Scharlatanerie, sondern auf allen System ein 32bit breiter unsigned int. Es interessiert niemanden, wie genau das umsetzt, außer Leuten, denen die Praxis sowieso wurscht ist und die nur akademisch meckern wollen. Aus der Ecke kam Pascal, deswegen ist das ja auch dermaßen verfrickelt und fragmentiert, weil man versuchen wollte, das nachträglich irgendwie praktisch erträglich zu machen. Und sowas wie "uint_fast_8t" kennt Pascal ja nichtmal. Weil es keine Systemprogrammiersprache ist. Daß Du die innere Logik von C schlichtweg nicht teilen magst, führt Dich zu dem Fehlschluß, sie existiere nicht. > Nun ja, deine Erfahrungen mit Pascal sehen ausgesprochen steinalt aus - > das ist etwa so, als wenn du heutzutage über K&R-syntax räsonniertest. Wie ich schon sagte, was glaubst Du denn, wieso es in Pascal (stellenweise..) heute sowas wie Pchar gibt. Endlich mal vernünftige Strings. Und die Pascal-Erweiterungen sind ja schön, nur leider hat es sich in lauter inkompatible Dialekte fragmentiert, das war auch in den 90ern schon so. > In C hat man es ja nicht mal geschafft, mit Integertypen aufzuräumen > UND Zeichentypen (char) von numerischen Typen zu trennen. Das ist auch gut so, weil ich es relativ häufig habe, daß ich numerische Zahlen in der Ausgabe auf Buchstaben mappen muß, und das geht mit Idiomen wie "my_number + 'a'" ganz wunderbar. > Ich halte das für eine kreuzgefährliche Grundeinstellung. Bieder und > in einfach gehaltener Quelle zu schreiben und das Optimieren dem > Compiler zu überlassen, ist also manchem unerträglich. Ich habe Dir recht detailiert auseinandergesetzt, was mich an Pascal gestört hat (18.10.2016 22:33), also tu nicht so, als gehe es um Freude am Risiko. Jedesmal, wenn die Rigidität der Sprache mich behindert hat und den Quelltext unübersichtlicher gemacht hat, habe ich über dieses Müsli geflucht. Im Grunde kann man das aber pascal auch nicht vorwerfen, weil Pascal als Spielzeugsprache für Lehrzwecke konzipiert worden ist.
W.S. schrieb: > Ähemm... dann verrate mir doch mal, wie strcat und Konsorten einen > String an einen anderen dranhängen - per magischem Endpunktfinden? ;-) Und du kannst uns mal verraten, mit welchem Trick in Sprachen,die bei Strings die Länge immer mit sich führen, diese Längen aus dem Nichts gezaubert werden. Mit stpcpy bzw stpncpy kann man übrigens Strings aneinanderhängen ohne dass es strlen()benötigt. Das Ende und damit die Länge ergibt sich aus dem Kopiervorgang.
A. K. schrieb: > Korrekt. Aber angesichts der Häufigkeit, wie der mittlerweile > Sicherheitsprobleme durch buffer overflows auftreten, fände ich etwas > mehr CPU für diesen Zweck eine sinnvolle Investition. Wenn man, mal salopp gesagt, jeden Zugriff erstmal prüfen wollte (auch auf arithmetische Überläufe am besten noch und so), dann werden aus jedem Zugriff zwei Zugriffe und ein Vergleich. Da Speicher aber heute sowieso schon den Flaschanhals darstellt, wäre das einfach keine Option. Man stelle sich mal vor, ein ganzes Betriebssystem wäre so lahm wie Eclipse. Na prost Mahlzeit, da kann man die Serverfarmen mal eben vervierfachen. Und schon gar nicht embedded, wo man nicht einfach mal eben so 3 Euro mehr für einen stärkeren Controller ausgeben mag - in Märkten, wo es teils um Centbeträge geht. Nee, das eigentliche Problem ist, daß zwar jeder von Kapselung und so spricht, das aber nur auf Code-Ebene meint. Auf Systemebene bauen wir uns (insbesondere mit IoT) aber das genaue Gegenteil, ein totales Spaghettikonzept, was aus demselben Grund in die Hose gehen muß wie Spaghetticode im kleineren Maßstab auch schon. Eine darartige Komplexität ist nicht beherrschbar, das wird man vom Machbarkeitswahn mal runterkommen müssen.
Nop schrieb: > Da Speicher aber heute > sowieso schon den Flaschanhals darstellt, In der Zugriffszeit ja, weniger vom Durchsatz her. Daumenregel: Zugriff auf direkt benachbarte Speicherstellen ist sehr günstig, Zugriff auf weit entfernte teuer. Der eigentliche Code von Checks ist relativ billig, sobald die nötigen Daten in Registern oder im L1-Cache vorliegen. Highend-CPUs (hab noch kein Eclipse auf einem AVR gesehen ;-) haben dafür genug Ressourcen, und Operationen, die keine Abhängigkeiten produzieren, sind dementsprechend günstig. Index/Range-Checks müssen auch nicht unbedingt bei jedem Zugriff stattfinden, selbst wenn die Sprache das dem Prinzip nach vorsieht. Denn solche Operationen können mitunter vom Compiler aus Schleifen rausoptimiert werden. Schlussendlich gilt die alte Regel von Optimierungen: Die weitaus meisten Codeteile kommen praktisch ohne sie aus, nur bei den Hotspots sind sie wirklich interessant. Für die Sicherheit gilt das freilich nicht, weshalb Checks an anderen Stellen als den Hotspots für die Performance wenig relevant sind.
A. K. schrieb: > Gib dem gleichen Programmierer mehr Geld und er wird besser? Das nicht. Aber: Gib dem gleichen Programmierer mehr Zeit und er (bzw. seine Produkte) werden besser. Aus Sicht der Chefetage wird er dadurch aber auch nur teuerer. DAS ist das eigentliche Problem... Diesem Dilemma haben wir ALLES zu verdanken, was wie heute haben. Insbesondere Programme, die für winzigste Funktionalitäten MB-weise Speicher und auf GHz-Maschinen ganze Sekunden Rechenzeit benötigen und die die meiste Zeit damit beschäftigt sind, irgendwelche Fehler zu produzieren, zu denen sie nicht einmal eine auf die tatsächliche Ursache des Fehlers hinweisende Fehlermeldung liefern können. Exceptionhandler ganz oben, ick hör dir trappsen... Noch höhere Hochsprachen und noch agilere Entwicklungsmethoden sollen die Antwort darauf sein. Da lachen doch die Hühner... Aber die Cheffes glauben nur zu gern diesen Bullshit der Vertriebsdroiden...
W.S. schrieb: > Dort findest du bei jeder Stringfunktion ein oder > mehrmaliges Aufrufen von strlen. > > Bevor du also hier von Anfängern schwafelst, solltest du dich besser > zuvor mal richtig informieren. dem zweiten Satz kann ich zustimmen, du solltest ihn aber auch selber anwenden, dann käme nicht so ein falscher Satz wie der erste zustande
>Das muß ein Schüler der C-Programmiersprache eben auswendig lernen. Er >muß dazu sich eben dran gewöhnen, daß es an vielen Stellen in C "eben so >ist wie es ist, basta!". >write(A:9:3, B:y*3:y); Das sagt mir z.B. gar nichts wenn ich nicht eingearbeitet bin - zumindest nicht mehr als ein Formatstring einem c Neuling. Ist es nicht immer so, dass man neue Sachen auswendig lernen muss wenn sie neu sind? So eine überlegene Selbsterklärende Logik ist da für mich nicht hinter. Ich kann wirklich kein Pascal. Write schreibt auf einen Kanal. Den Bildschirm oder eine Datei oder eine Uart? Was da wie formatiert wird ist absolut unlogisch wenn man nicht einiges gelernt, d.h. auswendig gelernt hat. Leuchtet das nicht ein? Es sind sich ja nun wirklich alle einig, dass c nicht unbedingt der Weisheit letzter Schluss ist, wägen aber auch Vor- und Nachteile ab. W.S., du hast zwar oben behauptet du würdest nichts verteufeln o.ä, aber das machst du nun mal unterschwellig eben doch.
for(;;) finde ich persönlich nicht so schön wie while(1) - aber das ist wirklich Geschmackssache. Meine Erfahrung mit C ist, dass man damit durchaus leserlichen Code schreiben kann - wenn man nicht meint, alle Gimmicks gleichzeitig nutzen zu müssen. Ich schreibe mittlerweile lieber fünf ausführliche Zeilen als eine Zeile engen Programmcode, gerne auch mit ein paar Klammern mehr als nötig. Dem Compiler ist es vollkommen egal und ich habe damit die besten Erfahrungen gemacht - auch bezüglich der Kommentierung. Stringverarbeitung mit Endmarker hat Vor- und Nachteile. Wer möchte, dass die Strings sich die Länge merken, kann problemlos eine entsprechende Ersatzbibliothek einbinden. Aber: er muss es nicht. Man hat die freie Wahl. Exzessive und insbesondere zeitkritische Stringverarbeitung ist mir im Bereich der µCs noch nicht begegnet. Meist landen die Strings eh im Flash. Ich hatte hier noch nie den Fall, dass die offizielle string.h nicht ausgereicht hätte. Stringverarbeitung ist immer nur ein unbedeutender Nebenschauplatz. Ich mag C für µC. Man sollte den Code halt nicht zu kompakt schreiben. Mittlerweile mag ich aber noch mehr Tcl auf µC ;-)
:
Bearbeitet durch Moderator
Zum Thema IoT: > Eine darartige Komplexität ist nicht beherrschbar, > das wird man vom Machbarkeitswahn > mal runterkommen müssen. Das hast du meine volle Zustimmung. Vor allem das Smart-Home und die tragbaren Körper-Sensoren werden derzeit viel zu früh in Richtung Internet gepusht.
c-hater schrieb: > > Noch höhere Hochsprachen und noch agilere Entwicklungsmethoden sollen > die Antwort darauf sein. Da lachen doch die Hühner... All das wurde im wesentlichen deshalb erfunden, um von der Abhängigkeit einzelner Programmierer mit Herrschaftswissen weg zu kommen. Ok, der Erfolg ist durchwachsen... Oliver
Nop schrieb: > Und außerdem wird man bei längeren Texten, wo man überhaupt solche > strlen-Probleme hat, auch in Pascal letztlich auf ein größeres > char-Array zurückgreifen, weil Pascalstrings für die Länge nur ein Byte > haben, also 255 Zeichen zulassen. Den Scheiß den Du hier über Pascalstrings erzählst kann man sich ja nicht mehr mit anhören. Ab Delphi 2.0 hat Borland einen neuen dynamischen Stringtyp ein geführt, der sich vom klassischen Pascalstring dadurch unterscheidet, daß er eben keine Längenbegrenzung auf 255 Zeichen hat. In diesem String ist der Zähler für die Stringlänge 32Bit lang. Demzufolge kannst Du damit 2^32 Zeichen (entspricht 4GB) in einem String speichern, was auch Deinen Ansprüchen bei weitem genügen sollte. Ja und man sollte es kaum glauben das selbst in diesen String am Ende das Nullzeichen angehängt wird, obwohl es auf Grund des Zähler eigentlich nicht gebraucht wird. Warum man das macht kann ich nicht sagen, es interessiert mich schlichtweg auch nicht. Wichtig ist für mich das ich mit dem Datentyp "string" einfach und effizient arbeiten kann und zum effizienten Arbeiten gehören für mich so einfache Sachen wie z.B. das Verbinden das Verbinden von Strings, was ja in Pascal bekanntermaßen durch einfache Addition von 2 Strings oder auch Chars gemacht wird. Ich brauche mich nicht darum zu kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich Compiler für mich und das ist auch gut so. Um so einen Kram möchte ich mich nicht kümmern müssen, diese Zeit und den erforderlichen Schmalz stecke ich lieber in die Umsetzung der Programmieraufgabe. Du solltest vielleicht mal ein Buch über Objectpascal zur Hand nehmen. Dort sind die Innovationen die zwischenzeitlich in Pascal Einzug gehalten haben meist sehr gut beschrieben - auch für resistente C-Programmierer. Und damit Du mich nicht gleich so dumm anmachst wie z.B. Zeno, hier gleich mal eine Quellenangabe : "Windowsprogrammierung mit Borland Delphi" von Hans-Peter Kalb - dies mal nur als eine Quelle. Dort ist ab S.26ff der Aufbau des neuen Pascalstrings hinreichend gut beschrieben. Ansonsten sind die von Borland bis Delphi 7 mitgelieferten Handbücher sehr gute Quellen des Wissens. Ach und dann sprichst Du in Deiner unendlichen Arroganz bei Pascal vom betreuten Programmieren - wie überheblich. Pascal oder besser Objectpascal wurde so um die Jahrhundertwende recht viel in den Firmen eingesetzt, weil zu diesem Zeitpunkt mit der Delphi IDE eine vernünftige IDE zur Verfügung stand mit der man schnell und effizient Programme mit GUI entwerfen konnte. Dank des in Objectpascal vorhandenen Exceptionhandlings war zudem auch eine effektive Fehlerbehandlung möglich, die man bei Programmen mit GUI oder auch Programmen welche viel mit Dateien arbeiten auch benötigt, weil man eben nicht, wie Du wieder mal mit einer nicht zu toppenden Arroganz behauptest, Fehler von vornherein vermeiden kann. Programme die mit 90% Userinteraktion arbeiten sind halt schon etwas anderes als ein 32kB großes µC Programm, welches im wesentlichen autark arbeitet und wo sich Interaktion mit dem Menschen auf das Drücken einiger klar definierter Knöpfchen beschränkt. Und weil das so ist braucht man für PC Programmierung halt Werkzeuge die einem die einem solche Sachen wie Objecte und Exceptions bereitstellen und das wird in aller Regel nicht C sein weil dieses selbiges nicht kennt. Für sowas müßte man schon sowas wie C++ nehmen und auch da wird keiner mehr irgendwelche Verrenkungen machen und irgendwelchen kruden Code einhacken, sondern man greift da auf Bibliotheken zurück und benutzt - soweit es möglich - die dort zur Verfügung gestellten Objecte. Der Pascalfan PS: Es ist schon erstaunlich wie lange man bloß wegen einer Frage zu for(;;) auf einem teils bedenklichen Niveau diskutieren kann.
W.S. schrieb: > C ist bekanntermaßen in weiten Teilen nicht logisch aufgebaut, es fehlen > Basismittel wie z.B. ein Boolean-Datentyp und vieles mehr, also wird das > per ordre de mufti erledigt. > Das muß ein Schüler der C-Programmiersprache eben auswendig lernen. Er > muß dazu sich eben dran gewöhnen, daß es an vielen Stellen in C "eben so > ist wie es ist, basta!". Du verwechselst Logik mit deinen Erwartungen, die du mit anderen Sprachen festgelegt hast. C ist mit die in sich logischste und konsistenteste aller Programmiersprachen, das ist auch ein Grund für ihren Erfolg. Bei C muss man sehr wenig auswendig lernen, aber man muss sie verstehen. C hat die wenigsten Schlüsselworte (von Forth mal abgesehen) und trennt klar zwischen Sprachbestandteilen und Funktionen (in Librarys). Dass man in C auch ohne Boolean-Datentyp alles machen kann, zeigt doch nur, dass Boolean als Datentyp überflüssig ist. Für den Fall, dass man viele Booleans kompakt speichern will, gibt es Bitfelder.
Pascalfan schrieb: > Und weil das so ist braucht man für PC Programmierung halt Werkzeuge die > einem die einem solche Sachen wie Objecte und Exceptions bereitstellen > und das wird in aller Regel nicht C sein weil dieses selbiges nicht > kennt. Ach je, das Argument kam jetzt zum hundertsten Mal alleine in diesem Thread, und es wird dadurch nicht wahrer. Kein Mensch programmiert PC-Klickibunti-Software in C. Aber die Welt besteht nicht nur aus PC-KlickiBunti. Da gibt es noch sehr viel mehr, sogar sehr viel mehr. Aber egal... Mit C ist es wie mit Kochgeräten: Thermomix , Backöfenautomatikprogramme, und was es da sonst noch an Küchen"helferlein" gibt, oder einfach ein scharfes Messer. Letzteres ist bei ungeübter Anwendung gefährlich, man muß tatsächlich lernen, damit umzugehen. Wenn man es aber kann, ist es unschlagbar schnell und flexibel. Trotzdem gibt es auch in der Sterneköche Anwendung für Küchenmaschinen. Oliver
Pascalfan schrieb: > Der Pascalfan > > PS: Es ist schon erstaunlich wie lange man bloß wegen einer Frage zu > for(;;) auf einem teils bedenklichen Niveau diskutieren kann. Erstaunlich ist auch, dass Leute die einfachen Forenregeln und auch ihren verwendeten Nicknamen vergessen. Ich möchte Dich also bitten, in Zukunft in diesem Thread wieder als der aufzutreten, der Du vorher warst - nämlich "Zeno". Dann können die anderen die Texte auch im Zusammenhang mit dem vorher von Dir Geschriebenen einordnen. Danke.
C ist vielleicht aus Sicht eines Elektrotechnikers "logisch". Aus der Sicht eines Mathematikers ist Haswell "logisch" und aus der Sicht eines Informatikers eher etwas aufgeräumtes wie z.B. C# oder Java. Im Endeffekt ist es Geschmackssache. C ist die Programmiersprache, die am nähesten an der Hardware dran ist. Noch näher ist dann tatsächlich nur noch mehr Assembler, aber ab da wirds dann wahrscheinlich selbst den Elektrotechnikern zu bunt. Das hat den schönen Nebeneffekt, dass Programme die in C geschrieben wurden, wenn man es richtig macht, am effizientesten sind. Dazu schreibt man am besten noch zeitkritische Routinen in Assembler und man holt das maximale aus seiner Hardware raus. Nun ist es aber leider so, dass es tausende verschiedene Prozessortypen, Betriebssysteme, etc. gibt und nicht jeder die Lust und/oder Zeit hat, sich durch 1000-seitige Programmierhandbücher für irgendwelche Prozessoren zu wälzen und dann zu überlegen, mit welchem Prozessorbefehl ich mein Programm noch schneller machen kann. Manche bzw. viele Menschen wollen einfach nur eine Programmiersprache, mit der man schnell und sauber ans Ziel kommt, und das geschriebene dann auf möglichst vielen verschiedenen Platformen läuft. Für Mikrocontroller gibt es sowas derzeit leider noch nicht. Da man hier alles in C programmiert muss man wirklich leider immer alles neu programmieren. Glücklicherweise gibt es aber ja mittlerweile tausende verschiedene Programmiersprachen, wo dann auch für jeden etwas dabe ist: Elektrotechniker, Informatiker, Mathematiker, Hausfrauen, Kinder, Rentner, Hipster, Betriebswirte, etc
Chris D. schrieb: > for(;;) finde ich persönlich nicht so schön wie while(1) - aber das ist > wirklich Geschmackssache. Es ist Geschmackssache, trotzdem ist es gegen die Philosophie von C. C wurde erdacht als Hardware unabhängiger Assembler Sprache, die, so wie von Assemblern gewohnt, genau das macht was der Programmierer schreibt. while(1) sagt dem Compiler erzeuge folgenden Maschinencode: lade Register mit 1 Registertest bedingter Sprung for(;;) sagt dem Compiler, erzeuge keinen Maschinencode sondern benutze diese Zeile als Rücksprung Adresse für die Schleife. Unumwunden, als ich mein erstes Berkeley C auf zwei 8 Zoll Disketten in die Hände bekam, wurde while(1) als Schwachsinn angesehen.
Pascalfan schrieb: > Warum man das macht kann ich nicht sagen, Aufruf von APIs/DLLs mit C Konvention.
Pascalfan schrieb: > Ab Delphi 2.0 hat Borland Lesen ist nicht Deine Stärke, ne? Borland hat.. das ist bereits FAIL. Weil es genau zu den proprietär und zu nichts kompatiblen Frickeleien am Sprachstandard vorbei zählt, deretwegen Pascal als Sprache so fragmentiert geworden ist! In C kann ich dasselbe Programm (abzüglich der Hardwarelayer) unter Windows, unter Linux und auf dem Mikrocontroller laufen lassen. Und Du kommst mit "Delphi unter Windows" an. Na super. Abgesehen davon würde ich für komplexe GUI-Projekte weder C noch Pascal verwenden, aber das nur am Rande. Nebenbei, gewöhn Dir mal Absätze an. Wenn Du im selben Stil so strukturlos programmierst wie Du schreibst, wundert es mich nicht, daß Du betreutes Programmieren brauchst.
A. K. schrieb: > Gib dem gleichen Programmierer mehr Geld und er wird besser? Nein. Eher: Suche dir bessere Programmierer und nimm die, auch wenn sie teurer sein mögen. Wenn man immer den billigsten nimmt und Lohndumping betreibt, bekommt man eben auf Dauer auch das, was man bezahlt. Das heißt nicht, dass billige Programmierer grundsätzlich schlecht wären und teure grundsätzlich gut, sondern nur, dass Sparwahn auch Konsequenzen hat. Das sieht man auch immer beim regelmäßigen Gejammer über angeblichen Fachkräftemangel. Meist sind genug Fachkräfte vorhanden, nur eben keine, die ihre Arbeitskraft für das Geld verkaufen wollen, das die Industrie bietet. W.S. schrieb: > Bevor du also hier von Anfängern schwafelst, solltest du dich besser > zuvor mal richtig informieren. Der Punkt ist, daß irgendwelche > sogenannten Stringfunktionen eben keinen tatsächlichen Stringtyp > ersetzen können. Sowas muß in die Sprachdefinition eingebaut sein und > der Compiler muß das selber handhaben - SELBER! verstehst du das? Du weißt aber, dass er das im Falle von GCC auch tut? Hier eine Liste der im Compiler eingebauten Standardfunktionen: https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/Other-Builtins.html#Other-Builtins Soviel dazu, sich erstmal zu informieren. > Im übrigen gilt das in entsprechender Form auch für die albernen > uint32_t Masche. Solange der Compiler SELBST keine anderen Datentypen > kennt als int mit den Geschmacksrichtungen long, short, unsigned, > signed, so lange ist das Zusammenschreiben irgendwelcher Headerdateien > nichts als Brimborium und Scharlatanerie. Und wieder nur blödes Gelaber ohne irgendwelche Begründung... Den Rest des Postings, der auch wieder nur die gleichen unbegündeten und unsinnigen Behauptungen wiederholt, C sei unlogisch, hab ich einfach mal entsorgt. Kommt eh nichts neues drin vor. W.S. schrieb: > Erstens: nimmt der Compiler die völlig variable Latte an all den > Parametern selbst auseinander und zerlegt sie in all das, was gebraucht > wird, > > Zweitens: läßt er logischerweise all die Funktionen weg, die konkret > nicht gebraucht werden Das hat C++ mit seinen Stream-Operatoren auch hinbekommen, ganz ohne dass man das im Sprachkern einbauen hätte müssen. > Drittens kann er auch mit variablen Formatangaben zurechtkommen (also > sowas wie write(A:9:3, B:y*3:y); Aha, und das soll man ganz ohne Vorwissen lesen können? Bei C beschwerst du dich ja darüber, dass man das nicht kann. > Die Chance zu sowas sehe ich alledings zu null an. In C hat man es ja > nicht mal geschafft, mit Integertypen aufzuräumen UND Zeichentypen > (char) von numerischen Typen zu trennen. Eine Trennung wird nicht erzwungen, aber es gilt die Regel: char für Text, signed und unsigned char zum rechnen. Wenn man diese einfache Regel beachtet, ist es auch nicht anders. Ich gebe aber zu, dass diese Regel offenbar viele nicht kapieren, oder sie denken zu viel darüber nach und meinen, schlauer als der Compiler sein zu müssen - mit zweifelhaftem Erfolg. Mir wäre auch lieber, wenn mit char nicht gerechnet werden könnte und man explizit in einen Typ "byte" oder so konvertieren müsste, um daraus einen Integer zu bekommen. Das im Nachhinein einzuführen, würde aber sehr viel bestehenden Code inkompatibel machen. W.S. schrieb: > A. K. schrieb: >> Nur sind Logik und Brauchbarkeit nicht deckend. > > Das ist allen verständnisvollen Programmierern völlig klar. Es geht ja > auch nicht darum hier irgendwas zu verteufeln, sondern es geht darum, > die Sache einfach nur nüchtern beim Namen zu nennen und dabei auch mal > deren Grenzen aufzuzeigen. Dann solltest du damit mal anfangen. > Der TO hat sich an for(;;) gestoßen - und zu Recht. > Formal ist das nicht falsch, aber es ist unleserlich, denn wir sind > Menschen und keine Maschinen. Ich habe überhaupt kein Problem damit, es zu lesen und zu verstehen, und das, obwohl ich keine Maschine bin. Was mache ich falsch? Jedenfalls ist irgendein goto-Gefrickel erheblich schlechter lesbar. Ich würde auch nicht erwarten, dass bei einem goto das Sprunglabel irgendwo vor dem goto selbst ist. Das ist einfach nur Spaghetticode, wie man ihn in den 80ern des letzten Jahrhunderts mal auf Home-Computern in BASIC verbrochen hat. >> Ich suche ein Zeichen, und wenn es nicht gefunden wird, muss ich diesen >> Fall eh separat behandeln. > > Nicht immer. ZB wenn man über den Punkt die Erweiterung eines > Dateinamens sucht. Wenn kein Punkt dabei ist, hat er keine Erweiterung > und der Leerstring ist korrekt. Naja, da heute selbst unter Windows mehrere Punkte in einem Dateinamen möglich sind, muss man sowieso weitersuchen, bis man den letzten Punkt gefunden hat. Ich muss also erstmal so lange suchen, bis nichts mehr gefunden wurde und danach das Ergebnis vom vorherigen Suchlauf nehmen, sofern vorhanden. >> Im übrigen kann man mit strchr auch explizit nach dem \0 selbst suchen. >> Ob man das braucht, sei mal dahingestellt, aber es ginge nicht, wenn >> dessen Adresse auch dann zurückgegeben würde, wenn das gesuchte Zeichen >> gar nicht gefunden wird. > > In C hat jeder String eine \0 und die wird auch von meiner Funktion > gefunden. Wie machst du dann die Unterscheidung? Pascalfan schrieb: > Wichtig ist für mich das ich mit dem Datentyp "string" einfach und > effizient arbeiten kann und zum effizienten Arbeiten gehören für mich so > einfache Sachen wie z.B. das Verbinden das Verbinden von Strings, was ja > in Pascal bekanntermaßen durch einfache Addition von 2 Strings oder auch > Chars gemacht wird. Ich brauche mich nicht darum zu > kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich > Compiler für mich und das ist auch gut so. Auf dem PC ja. Auf einem kleinen 8-Bitter wäre das recht verheerend, wenn im Hintergrund ständig neu Speicher für die Ergebnisse dieser Operationen allokiert würde. > PS: Es ist schon erstaunlich wie lange man bloß wegen einer Frage zu > for(;;) auf einem teils bedenklichen Niveau diskutieren kann. Ich finde das nicht weiter tragisch. Die ursprüngliche Frage ist beantwortet, und die Diskussion hat sich danach in eine andere Richtung entwickelt. Ich sehe keinen Schaden darin, weiter zu diskutieren.
Nop schrieb: >Abgesehen davon würde ich für komplexe GUI-Projekte weder C noch Pascal >verwenden, aber das nur am Rande. gerade Pascal ist dafür (am besten) geeignet (siehe Lazarus, oder firemonkey jenachdem) Pascal für AVR usw. gibt es auch.. tortzdem wird man für den µC "C" verwenden, aber nicht weil die Sprache "C" besser ist...
Rolf Magnus schrieb: >>> Im übrigen kann man mit strchr auch explizit nach dem \0 selbst suchen. >>> Ob man das braucht, sei mal dahingestellt, aber es ginge nicht, wenn >>> dessen Adresse auch dann zurückgegeben würde, wenn das gesuchte Zeichen >>> gar nicht gefunden wird. >> >> In C hat jeder String eine \0 und die wird auch von meiner Funktion >> gefunden. > > Wie machst du dann die Unterscheidung? Was muss da unterschieden werden? Wenn man mit strchr das Nullbyte sucht, sucht man das Ende des Strings und da jeder String mit \0 beendet wird, gibt es den Fall "nicht gefunden" garnicht, bei dem strchr NULL herausgeben würde. Übrigens gibt es in der GNU-CLib inzwischen auch strchrnul, das sich genauso verhält wie meine Funktion mstrchr.
>da jeder String mit \0 beendet >wird, das ist doch das Problem diese Annahme.. verwendet (irgendjemand) den code dann irgendwann mal z.b in einer Library und ein "Böser bube" von extern ruft den Code auf, hat der String halt mal keine \0 mehr...
Pascalfan schrieb: > Wichtig ist für mich das ich mit dem Datentyp "string" > einfach und effizient arbeiten kann und zum effizienten Arbeiten gehören > für mich so einfache Sachen wie z.B. das Verbinden das Verbinden von > Strings, was ja in Pascal bekanntermaßen durch einfache Addition von 2 > Strings oder auch Chars gemacht wird. Ich brauche mich nicht darum zu > kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich > Compiler für mich und das ist auch gut so. Um so einen Kram möchte ich > mich nicht kümmern müssen, diese Zeit und den erforderlichen Schmalz > stecke ich lieber in die Umsetzung der Programmieraufgabe. Das gilt für den PC oder Controller mit genügend RAM und/oder vernünftiger Speicherverwaltung. Auf kleineren embedded Systemen kann das verdammt schnell in die Hose gehen. Wenn das Programm dann nicht mehr das macht was es soll weil es keine 100Byte Speicher mehr am Stück für den String kriegt hat obwohl in der Summe noch genügend da ist. Und wenn das dann auch noch davon abhängig ist in welcher Reihenfolge die vorausgegangenen Speicheranforderungen kamen wird es komplett undurchsichtig. Dabei kann dir aber auch kein Compiler helfen, egal ob C oder Pascal. Am Ende ist es besser man kümmert sich da selbst drum als das man hofft es wird schon irgendwie gehen. Bei der PC-Programmierung ist es heute eh der Fall, dass sich niemand mehr um den Speicher Gedanken macht. Und auch nicht darum innere Schleifen darauf hin zu Optimieren, die Anzahl von Speicheranforderungen und Freigaben zu reduzieren. Gerade bei Strings sind die klassische C-Methoden in engen zeitkritischen Schleifen teilweise 10er Potenzen schneller als in Hochsprachen. Wenn eine fiktive substr()-Funktion erst mal Speicher anfordern muss um dann einen Teil des Strings zu kopieren, kann's nicht mehr schnell gehen. Klar würde es auch da Wege geben das elegant zu lösen. Das Problem ist nur, keiner weiß wie die interne Implementierung der Strings in Pascal o.ä. wirklich abläuft. Als Beispiel mal eine fiktive Aufgabe: In einer csv-Datei stehen 100Mio Vor- plus Nachnamen. Die soll in eine 2. Datei kopiert werden, allerdings nach Nachnamen sortiert. Wenn jetzt die ach so gelobte Hochsprache nur für die interne Darstellung 200Mio mal 2-50Byte Speicher anfordert und beim Sortieren mit dynamische Strings hantiert, hat sie von vornherein gegen eine intelligente C-Variante verloren. Klar erfordert das auch Gehirnschmalz und birgt Gefahren beim Hantieren mit Pointern. Der Entwickler kann aber selbst entscheiden was er wie will. Bei Sprachen die immer und überall mit dynamischen Strings arbeiten muss ich erst mal Versuchsreihen machen um zu erahnen was intern schnell und was langsam geht.
besucher47 schrieb: >>da jeder String mit \0 beendet >>wird, > > das ist doch das Problem > diese Annahme.. > > verwendet (irgendjemand) den code dann irgendwann mal z.b in einer > Library > und ein "Böser bube" von extern ruft den Code auf, hat der String halt > mal keine \0 mehr... In C wird jeder String mit \0 beendet. Wenn ein "böser Bube" den C-Code in einer andern Sprache verwendet, kann natürlich nichts garantiert werden. Aber ich muss mich korrigieren. Je nach Implementation kann strchr mit \0 aufgerufen auch immer NULL zurückgeben. Dann ist es nicht geeignet, um das Stringende zu suchen. Mit strchrnul geht das.
Es wird nominell jeder String mit \0 beendet. Aber es wird nicht automatisch jedes char-array mit \0 beendet, in dem ein Haufen Zeichen liegen, die ein String sein sollen. Bei char s[10]; strncpy(s, "0123456789abcdef", sizeof s); liegt kein \0 drin, und bei strlen(s) wird es dann interessant.
:
Bearbeitet durch User
A. K. schrieb: > Es wird nominell jeder String mit \0 beendet. Aber es wird nicht > automatisch jedes char-array mit \0 beendet, in dem ein Haufen Zeichen > liegen, die ein String sein sollen. Bei > char s[10]; > strncpy(s, "0123456789abcdef", sizeof s); > liegt kein \0 drin, und bei strlen(s) wird es dann interessant. Was wird interessant? Das Programm stürzt bestenfalls ab. Alleine die Tatsache, dass so etwas überhaupt möglich ist, spricht gegen C.
A. K. schrieb: > strncpy(s, "0123456789abcdef", sizeof s); > liegt kein \0 drin, und bei strlen(s) Offensichtlich ist Dir ja klar, daß die nicht-n-Funktionen heikel sein können, deswegen nimmst Du zurecht strncpy? Wieso nimmst Du dann aber nicht auch strnlen?
A. K. schrieb: > Es wird nominell jeder String mit \0 beendet. Aber es wird nicht > automatisch jedes char-array mit \0 beendet, in dem ein Haufen Zeichen > liegen, die ein String sein sollen. Bei > char s[10]; > strncpy(s, "0123456789abcdef", sizeof s); > liegt kein \0 drin, und bei strlen(s) wird es dann interessant. Gutes Beispiel dafür dass nicht immer stncpy der Heilsbringer ist und der Einsatz einem davon befreit zu denken. Interessant wird es wenn man danach strlen(s) macht und alles erst mal korrekt aussieht. Man wundert sich u.U. dann plötzlich warum die Release-Version abschmiert weil strlen() plötzlich da liest wo nichts mehr ist...
Nop schrieb: > Wieso nimmst Du dann aber nicht auch strnlen? Weil es strncpy seit Anbeginn von C gibt, strnlen aber noch recht frisch ist. Posix kennt das erst in der 2008er Version.
Tasg schrieb: > Was wird interessant? Das Programm stürzt bestenfalls ab. Alleine die > Tatsache, dass so etwas überhaupt möglich ist, spricht gegen C. Die Tatsache dass man mit einem Auto gegen den Baum fahren kann wenn man gerade an Handy oder Frau fummelt, spricht eindeutig gegen Bäume am Straßenrand. Besser wären Postkutschen, Pferde interessieren sich für beides nicht.
temp schrieb: > Die Tatsache dass man mit einem Auto gegen den Baum fahren kann wenn man > gerade an Handy oder Frau fummelt, spricht eindeutig gegen Bäume am > Straßenrand. Insbesondere spricht es gegen Airbags. Der Darwin'schen Auslese wegen.
temp schrieb: > In einer csv-Datei stehen 100Mio Vor- plus Nachnamen. Die soll in eine > 2. Datei kopiert werden, allerdings nach Nachnamen sortiert. [...] > von vornherein gegen eine intelligente C-Variante verloren. Klar erfordert > das auch Gehirnschmalz und birgt Gefahren beim Hantieren mit Pointern. Mir ist nicht ganz klar, was das in so einem Fall angemessene Vorgehen (externer Mergesort z.B.) generell mit C und Zeigern zu tun hat. > Wenn jetzt die ach so gelobte Hochsprache nur für die interne Darstellung > 200Mio mal 2-50Byte Speicher anfordert Das könnte man in C genauso versuchen wie in einer anderen Programmiersprache. Was soll das zeigen?
Gemeint ist wohl, dass es oft günstiger ist, Pointer auf Daten zu sortieren, als die Daten selbst. Allerdings kann man statt Pointern auch einen Indexvektor sortieren.
:
Bearbeitet durch User
Quax schrieb: > Das könnte man in C genauso versuchen wie in einer anderen > Programmiersprache. Was soll das zeigen? A. K. schrieb: > Gemeint ist wohl, dass es oft günstiger ist, Pointer auf Daten zu > sortieren, als die Daten selbst. Allerdings kann man statt Pointern auch > einen Indexvektor sortieren. Klar der Weg der Hochsprache ist ja: Für jede Zeile einen String und die in ein Array. Womit man schon die ersten zig. Mio Speicheranforderungen gemacht hat. Nodejs und JavaScript legen sich hierbei schon die Karten. Was da in Pascal passiert kann ich nur erahnen. Wenn beim Sortieren noch mit Substrings gearbeitet wird, geht der Reigen weiter. Bei bekannter Anzahl Zeilen braucht man in C genau 2 Speicheranforderungen. Auf alle Fälle aber niemals so viel wie zu sortierende Elemente. Der Rest ist reines Pointerhandling. Ist zwar etwas komplexer zu Programmieren aber manchmal kommt es eben auf Geschwindigkeit an. Und wir sprechen hier nicht von Prozenten sondern von Welten.
Wie schon vorhin gesagt: Ob du ein Array aus Pointern sortierst, oder eines aus Indizes, das schenkt sich wenig.
laberts doch nicht immer von Sachen von denen ihr keine Ahnung habt.. ein String in Pascal ist auch ein Pointer, sogar mit Referenzzählung..
Pascalfan alias Zeno schrieb: > Den Scheiß den Du hier über Pascalstrings erzählst kann man sich ja > nicht mehr mit anhören. oha - große töne spucken > Ab Delphi 2.0 hat Borland einen neuen dynamischen Stringtyp ein geführt, > der sich vom klassischen Pascalstring dadurch unterscheidet, daß er eben Und dann selbst Äpfel mit Birnen vergleichen. Alle reden hier von Pascal und du fängst von Delphi/ObjectsPascal an. Das ist wie c vs c++. Das sind zwei einfach 2 verschiedene Sprachen. Das ist als würde ich schreiben
1 | Den Scheiß den Du hier über C-"Strings" erzählst kann man sich ja nicht mehr mit anhören. |
2 | Ab C++ hat Bjarne Stroustrup einen neuen dynamischen Stringtyp |
3 | std::string ein geführt, der sich vom klassischen C-"Strings" dadurch |
4 | unterscheidet, daß er eben seine Länge speichert. |
5 | Ja und man sollte es kaum glauben |
6 | das selbst in diesen String am Ende das Nullzeichen angehängt wird, |
7 | obwohl es auf Grund des Zähler eigentlich nicht gebraucht wird. Warum |
8 | man das macht kann ich nicht sagen, es interessiert mich schlichtweg |
9 | auch nicht. Wichtig ist für mich das ich mit dem Datentyp "std::string" |
10 | einfach und effizient arbeiten kann und zum effizienten Arbeiten gehören |
11 | für mich so einfache Sachen wie z.B. das Verbinden das Verbinden von |
12 | Strings, was ja in c++ bekanntermaßen durch einfache Addition von 2 |
13 | Strings oder auch Chars gemacht wird. Ich brauche mich nicht darum zu |
14 | kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich |
15 | die Klasse |
16 | [Anmerkung: hier stand vorher Compiler - ich bin mir ziemlich sicher, |
17 | dass das auch für Objectspascal falsch ist, weil das zur Laufzeit gemacht wird] |
18 | für mich und das ist auch gut so. |
19 | Um so einen Kram möchte ich mich nicht kümmern müssen, |
20 | diese Zeit und den erforderlichen Schmalz |
21 | stecke ich lieber in die Umsetzung der Programmieraufgabe. |
22 | Du solltest vielleicht mal ein Buch über C++ zur Hand nehmen. |
23 | Dort sind die Innovationen die zwischenzeitlich in C++ Einzug |
24 | gehalten haben meist sehr gut beschrieben - auch für resistente |
25 | Pascal-Programmierer. |
:
Bearbeitet durch Moderator
>Alle reden hier von Pascal
jeder redet von dem Pascal dass am besten in seine Argumentation passt..
die einen von einem Aktuellen (z.b aktuelle FPC)
die anderen von uralten (warum auch immer)
besucher47 schrieb: > jeder redet von dem Pascal dass am besten in seine Argumentation passt Wer aber mit modernen objektorientierten Pascal-Dialekten argumentiert, der sollte diese dann auch gegen aktuelle C++-Versionen vergleichen, damit es nicht Äpfel und Birnen werden.
besucher47 schrieb: >>Alle reden hier von Pascal > > jeder redet von dem Pascal dass am besten in seine Argumentation passt.. > > die einen von einem Aktuellen (z.b aktuelle FPC) Genau das ist das Problem: "z.B.". Jeder redet von einem anderen Pascal, weil es das Pascal nicht mehr gibt, im Gegensatz zu C. Und wie Vlad schon ausgeführt hat, ist es ziemlich dämlich, Lazarus mit C zu vergleichen. Das ist für Pascal das, was C++ für C ist: Eine neue Sprache, die darauf aufbaut und weitgehend dazu kompatibel ist, aber viele neue Möglichkeiten wie OOP und Exceptions mitbringt. > die anderen von uralten (warum auch immer) Weil es ein sinnvollerer Vergleich ist.
Die Diskussion um C und Pascal (eigentlich ja sowieso offtopic, aber sei's drum) dreht sich ziemlich im Kreis, weil von einigen Leuten Dinge über einen Kamm geschert werden, die eigentlich separat betrachtet werden sollten. Deswegen möchte ich (wahrscheinlich erfolglos ;-)) versuchen, etwas Ordnung in die Diskussion zu bringen und dabei die vier letzten Kommentare von Vlad, besucher47, Jörg und Magnus aufgreifen: 1. Pascal und Object-Pascal sind (ähnlich wie C und C++) zwei verschiedene Sprachen. Object-Pascal ist zwar der Nachfolger von Pascal, deswegen ist aber Pascal noch lange nicht verschwunden. Um die Unterschiede klarer hervorzuheben, verwende ich im Folgenden die Begriffe "ISO-Pascal" für das prozedurale Pascal, "Object-Pascal" für das objektorientierte Pascal und "Pascal-Familie" als Oberbegriff für beide zusammen. Entsprechend ist "C-Familie" der Oberbegriff für C und C++. 2. Die Argumente werden teils auf PC- und teils auf µC-Anwendungen bezogen (wobei mit µC in diesem Zusammenhang einfache Mikrocontroller wie der AVR, PIC oder 8051 gemeint sind). Da für PCs und µCs völlig unterschiedlich Anforderungen gelten, sollte man diese Argumente nicht durcheinanderwürfeln. Es gibt also sowohl in der C- als auch in der Pascal-Familie Sprachen mit prozeduraler (C und ISO-Pascal) und solche mit objektorientierter Ausprägung (C++ und Object-Pascal). Alle vier Sprachen gibt es sowohl für PCs als auch für kleine µC (wie AVRs, PICs und 8051er). Die µC-Varianten sind dabei mehr oder weniger eingeschränkt. Hier ist eine Übericht der vier Kategorien:
1 | prozedural objektorientiert |
2 | ————————————————————————————————————————————————— |
3 | PC K: PC-PP K: PC-OOP |
4 | C: C C: C++ |
5 | P: ISO-Pascal P: Object-Pascal |
6 | V: vollständig V: vollständig |
7 | ————————————————————————————————————————————————— |
8 | µC K: µC-PP K: µC-OOP |
9 | C: C C: C++ |
10 | P: ISO-Pascal P: ISO-Pascal |
11 | V: leicht abgespeckt V: stark abgespeckt |
12 | ————————————————————————————————————————————————— |
Die einzelnen Einträge der Tabelle bedutet: K: Kategorie (zur Referenzierung im folgenden Text) C: Sprache aus der C-Familie P: Entsprechende Sprache aus der Pascal-Familie V: Vollständigkeit der Sprachimplementierung Diese Kategorien sind nicht etwas virtueller Natur, denn für allen vier sind Compiler bzw. Entwicklungsumgebungen verfügbar. Ein paar Beispiele (ohne Anpspruch auf Vollständigkeit): C-Familie: PC-PP: GCC, Microsoft Visual C++ (im C-Modus) PC-OOP: G++, Microsoft Visual C++ µC-PP: AVR-GCC, IAR C, MikroE mikroC, MPLAB XC8, SDCC µC-OOP: AVR-G++, IAR C++ Pascal-Familie: PC-PP: Free Pascal (im ISO-Modus), GNU Pascal (Entwicklung eingestellt) PC-OOP: Free Pascal, Delphi µC-PP: MikroE mikroPascal, E-LAB AVRco, Turbo51 µC-OOP: Free Pascal für AVR Es sollte klar sein, dass Compiler bzw. deren Sprachumfang nur innerhalb einer der vier Kategorien (PC-PP, PC-OOP, µC-PP und µC-OOP) sinnvoll verglichen werden können. Damit relativiert sich auch die Diskussion um die verwendeten String- Typen: Dynamische Strings (nahezu) beliebiger Länge gibt es ausschließlich in der Kategorie PC-OOP. Für string-intensive Ausgabestellungen auf dem PC wird man deswegen sinnvollerweise die objektorientierten Varianten, also C++ oder Object-Pascal wählen. Strings in PC-PP, µC-PP und µC-OOP sind statisch, d.h. sie haben zwar eine variable Länge, aber dennoch eine feste Gesamtkapazität, die bei der Variablendeklaration festgelegt wird. Ihre Länge wird entweder über ein Längenbyte (0..255) oder eine Null-Markierung am Ende angegeben. Das gilt insbesondere auch für Free Pascal auf dem AVR, wo es im Gegensatz zur PC-Version nur ShortStrings (Char-Array mit Längeninformation im ersten Array-Element), jedoch keine AnsiStrings (dynamische Strings mit 32-Bit-Längeninformation). Deswegen kann darüber disuktiert werden, ob die nullterminierten Strings vonn C oder die ShortStrings von Pascal besser sind. Ebenso können die C++-Strings mit den AnsiStrings von Object-Pascal verglichen werden. Der Vergleich von nullterminierten mit AnsiStrings oder von C++-Strings mit ShortStrings kann aber aus den genannten Gründen überhaupt nicht als Grundlage für den Vergleich der beiden Sprachfamilien dienen. Ebenso unsinnig ist es, die Objektorientierung von Object-Pascal als Vorteil gegenüber C aufzuführen. Denn für jede Plattform, auf der Object-Pascal läuft, ist auch ein C++-Compiler verfügbar (nur umgekehrt nicht).
Jobst Q. schrieb: > Stringhandling ist die Bearbeitung von Strings beim Lesen und Schreiben. > Da der String in C nichts anderes ist als ein Zeiger auf den Anfang, O ha, Strings sind was anderes als Streams. Junge, sowas passiert mir selbst dann nicht, wenn ich mal zu tief ins Weinglas geschaut habe... Jörg W. schrieb: > Yep, und damit bist du komplett festgenagelt auf die Ausgabekanäle, > wie sie in den Sprachumfang gegossen worden sind. Das ist doch genau > einer der Kritikpunkte an Pascal oben, dass man das, was der Compiler > bei write[ln] macht, nicht im eigenen Code ebenfalls zur Verfügung > hat. Alles, was als Ausgabekanal nicht bereits so ist, dass es von > der Implementierung als "Datei" betrachtet würde, kann man damit > vergessen. Sag mal, wovon redest du eigentlich? "festgenagelt"? Au weia! write ist die Stream-Ausgabefunktion von str und du hast mit write schlichtweg alle im jeweiligen Betriebssystem zugreifbaren Kanäle zur Verfügung. Auch stdout, wenn du das magst. Wie kommst du zu der Aussage, daß man das nicht im eigenen Code hätte? Ich will mal davon absehen, daß wir hier im "PC-Programmierung"-Forum sind, wenn du schon von µC anfängst. Also könntest du dir deinen String per str in gleicher Weise und gleichem Funktionsumfang wie write erzeugen und ihn dann verfrachten, wohin du ihn willst. Der Knackpunkt ist die Frage "Übersetzungsarbeit zur Übersetzungszeit oder zur Laufzeit?". Wählt man das erstere, dann muß man's eben entweder selbst tun oder es muß in den compiler eingebaut sein, will man's der Zielhardware aufbürden, dann muß man eben sowas wie printf wählen - was ich aus ideologischen Gründen ablehne: Was man am PC per Compiler erledigen kann, sollte man nicht einem µC-Zielsystem überhelfen. Es ist ja nicht so, daß Pascal für sowas wie printf ungeeignet wäre, es gibt seit langem dafür Entsprechungen für Leute, die's nicht lassen können. Aber es ist überflüssig, weil man auf dem PC mit str und write wesentlich mächtigere Ausdrucksmittel hat - und weil all sowas wie printf, write und Konsorten von früher her vorgesehen sind für Kommandozeilen-technik und deshalb für moderne GUI-Anwendungen überhaupt nicht mehr gebraucht werden. Auf den µC mache ich das zwecks Vermeidung solchen Overheads so, daß ich das, was auszugeben ist, selber separat hinschreibe. Siehe Lernbetty, da hab ich sowas vorgeturnt. Das Ergebnis ist, daß es kompakter und schneller ist als alle printf-Implementationen. Also, das Herumgejammer von C-Leuten über write bei pascal finde ich ausgesprochen albern - und obendrein würde man es in einer Firmware auf einem µC auch in Pascal anders machen als in einem Programm auf einem PC. Da sind ja doch wesentliche Unterschiede. nochwas: A. K. schrieb: > Die fehlende > Unterscheidung ist eine Art Axiom von C, ob man es mag oder nicht. > ... > C dafür zu kritisieren, dass es C bleibt, ist also unredlich. Du musst C > deshalb nicht mögen, aber die Axiome von C sind fixiert. Tja, ich weiß. Das Problem steckt dennoch tiefer: C ist derzeit eine Monokultur - zumindest in µC-Gefilden. Das ist schlecht, ganz schlecht. Die Menschheitsgeschichte sollte es uns unmißverständlich gelehrt haben, daß Monokulturen aller Art immer schlecht sind, und uns fehlen mittlerweile weitgehend die Alternativen in der Programmierung. Was ähnliches sehe ich in der Hardware bei den Cortexen. Jaja, man kann beides derzeit trefflich benutzen, das ist gar keine Frage, aber es fehlt die Konkurrenz und damit wächst ubiquitär der Kalk - selbst schon in den Köpfen von Jungingenieuren. Jetzt kann man Mutmaßungen über den Zeitverlauf anstellen und jeder kann sich fragen, ob man noch selbst reinschlittert in die zu erwartenden Malessen oder wer in x Jahren Rentner oder schon tot ist. Fest steht, DASS es irgendwann mal kracht. Ich z.B. will mir garnicht vorstellen müssen, daß ein C wie es heutzutage gebraucht wird, in 50 Jahren immer noch in die dann aktuellen Cortexe gebrutzelt wird - mit all den Uralt-Lasten aus seiner Steinzeit. Eigentlich wäre Findigkeit, Innovation und sowas wie Frontrunning hier bei uns dringendst vonnöten, denn nur durch sowas können wir den Wohlstandsberg so lala aufrechterhalten, auf dem wir derzeit leben. Wenn nicht, dann gute Nacht unseren Enkeln. Nun, Innovation geht bei den Programmiersprachen nur dann, wenn man entweder eine renovierfähige Sprache ausbaut oder eine ganz neue erfindet. Aber mit einer renovierunwillgem C-Gemeinde läßt sich das nicht backen. W.S.
Yalu X. schrieb: > Strings in PC-PP, µC-PP und µC-OOP sind statisch, d.h. sie haben zwar > eine variable Länge, aber dennoch eine feste Gesamtkapazität, die bei > der Variablendeklaration festgelegt wird. Yalu, erstmal Dank für deine Bemühungen, in diesen wilden Haufen etwas Ordnung bringen zu wollen. Aber bei PC-PP liegst du falsch. Seit rund 20 Jahren (also seit Win95), als Pascal-Compiler für die Win32-Plattform aufkamen, sind die Strings dynamisch geworden - das ist die Zeit nach BP7. Ich hab hier immer noch ein steinaltes Virtual-Pascal, wo dieses als Standard-String dient. Wenn man einen "alten" String haben will, muß man dediziert 'shortstring' nehmen. Ich sehe allerdings ein, daß man auf einem µC in ganz vielen Fällen keine bis zu 2 GB großen Strings benötigt. Aber: Es ist alles drin, vom Kleinsten bis zum schier unendlich großen bei Pascalimplementierung für 64Bit Systeme. W.S.
W.S. schrieb: > Eigentlich wäre Findigkeit, Innovation und sowas wie Frontrunning hier > bei uns dringendst vonnöten Nur braucht Innovation nicht nur Veränderung, sondern vor allem auch Verbesserung. Wir werden uns darüber eher nicht einig werden, aber Du siehst hier ja zumindest, daß die Ansicht, Pascal sei eine Verbesserung im Vergleich zu C, offensichtlich kontrovers ist.
W.S. schrieb: > Jobst Q. schrieb: >> Stringhandling ist die Bearbeitung von Strings beim Lesen und Schreiben. >> Da der String in C nichts anderes ist als ein Zeiger auf den Anfang, > > O ha, Strings sind was anderes als Streams. Junge, sowas passiert mir > selbst dann nicht, wenn ich mal zu tief ins Weinglas geschaut habe... Du willst mir also weismachen, dass die Stringbehandlung, in der ich über Jahrzehnte tätig war, eigentlich Streambehandlung war? Bevor mich das in die Verzweiflung treibt, schau ich doch mal im Lexikon nach: "Eine Zeichenkette oder (aus dem Englischen) ein String ist in der Informatik eine Folge von Zeichen (z. B. Buchstaben, Ziffern, Sonderzeichen und Steuerzeichen) aus einem definierten Zeichensatz. Zeichen können sich in einer Zeichenkette wiederholen, die Reihenfolge der Zeichen ist definiert. Zeichenketten sind somit Sequenzen aus Symbolen mit endlicher Länge." https://de.wikipedia.org/wiki/Zeichenkette und "Mit Datenströmen (englisch data streams) bezeichnet man in der Informatik einen kontinuierlichen Fluss von Datensätzen, dessen Ende meist nicht im Voraus abzusehen ist; die Datensätze werden fortlaufend verarbeitet, sobald jeweils ein neuer Datensatz eingetroffen ist. Die einzelnen Datensätze sind dabei von beliebigem, aber festem Typ. Die Menge der Datensätze pro Zeiteinheit (Datenrate) kann variieren und evtl. so groß werden, dass die begrenzten Ressourcen zur Weiterverarbeitung nicht ausreichen und der Empfänger entsprechend reagieren muss (z. B. verwerfen von Datensätzen). Im Gegensatz zu anderen Datenquellen können Datenströme nur Satz um Satz fortlaufend verarbeitet werden - insbesondere ist im Gegensatz zu Datenstrukturen mit wahlfreiem Zugriff (wie z. B. Arrays) meist nur ein sequentieller Zugriff auf die einzelnen Datensätze möglich." https://de.wikipedia.org/wiki/Datenstrom Also bist du wohl derjenige, der zu tief ins Weinglas geschaut hat.
Und nochwas zum Thema "Innovation". Die bestehende Quellcodemenge, die für C bereits verfügbar ist, stellt einen erheblichen geschaffenen Wert dar. Wollte man den wegwerfen, dann müßte eine Alternative soviel besser sein, daß sich das in absehbarer Zeit überhaupt lohnen würde. Ansonsten wäre es keine Innovation, sondern lediglich unterm Strich schädlicher Aktionismus, der Innovation vortäuschen soll. Auf dem PC, mit GUI-Framneworks usw., hat man diesen Schritt gemacht, weil reines C dafür von vornherein ein ziemlicher Krampf war und nie so richtig gut funktioniert hat. Nur, da ist Pascal auch keine Alternative, weil es lediglich eine andere prozedurale Sprache ist, die obendrein auch noch fragmentiert ist wie Hulle. Es gibt nunmal nicht nur revolutionäre Fortschritte, sondern auch evolutionäre. Zwischen Umbrüchen wird erstmal der Bestand verbessert und optimiert. Die Erwartungshaltung, man wolle nur noch Umbrüche haben, ist fehlgeleitet, weil man dann nur noch deren Kosten hat, ohne aber von ihrem Nutzen danach zu profitieren. Und obendrein gibt es dann auch noch Rückschritte und klare Verschlechterungen. Wenn man heutzutage Windows, Spiele usw. ohne Onlineanbindung gar nicht mehr betreiben kann, ist das ein Beispiel dafür. Die fliegenden Autos mit Atomantrieb, von denen man in den 50ern als Zukunfts-Innovation geschwärmt hat, sind ja glücklicherweise nie auch nur ins Versuchsstadium gekommen. Wo ich für die Zukunft Potential sehe, ist Parallelisierung. Die einzelnen CPU-Kerne werden kaum noch stärker, das Ende der Fahnenstange ist so ziemlich erreicht. Aber man kann immer mehr parallel davon haben, was nur derzeit kaum Sinn ergibt, außer für Spezialanwendungen. Und selbst da ist es schwierig. Sowohl prozedural als auch mit OOP kommt man da nicht weiter. Funktionale Sprachen wären ein Weg, weil es dort keinen state gibt, den man gegen Parallelismus verwalten müßte. Deswegen kam Google mit Map-Reduce ums Eck, während Microsoft immer noch vergeblich versucht, überhaupt eine Suchmaschine zu etablieren. Funktionale Sprachen wie Lisp sind erheblich langsamer als C, das ist Fakt. Selbst wenn Lisp compiliert wird. Allerdings könnte man es in C schon grundsätzlich völlig vergessen, eine Anwendung zu schreiben, die auf ein paar zigtausend, geschweige denn hunderttausenden Knoten skaliert. Gut, Lisp hat sich aus gutem Grund nie ernsthaft durchgesetzt (((und das nicht wegen der Klammern))), aber ich sehe bei funktionaler Programmierung für große Anwendungen durchaus Potential. Jenseits von C. ;-)
Nop schrieb: > Wollte man den wegwerfen... Soll ich dir aufzählen, was in der Geschichte so alles weggeworfen worden ist? Geht nicht, es ist viel zu viel. Jedes Ding hat seine Zeit und mir kommt dabei Mephisto aus Faust in den Sinn: "denn alles was entsteht, ist wert, daß es zugrunde geht;" - allerdings teile ich Mephistos Meinung nicht, denn es war auch mal wert, daß es entstanden ist und benutzt wurde. Ob man das nun ausgerechnet an Pascal festmachen will, ist eigentlich egal, es kommt nur drauf an, es eben nicht weiter so zu machen wie C. Egal, wie groß die Berge der zurückliegenden Quellcodes auch sein mögen. Apropos: nicht der konkrete Quellcode ist wertvoll, sondern der Wert steckt in den gefundenen Algorithmen und gewonnenen Erkenntnissen. Typisches Beispiel ist die FFT, egal ob sie in Assembler, C oder Pascal formuliert ist. Der Wert von Einsteins Relativitätstheorie steckt ja auch nicht im Papier des Buches, wo es gedruckt ist. Ansonsten geb ich dir durchaus Recht -mit einer Einschränkung: Wir alle können nur die Historie analysieren und Erkenntnisse draus ziehen und wir können eine Ansicht über die Gegenwart haben - aber in die Zukunft blicken kann keiner und sie hat schon immer für Überraschungen gesorgt. Vielleicht sehen es künftige Generationen als unnütz an, die Rechentechnik immer weiter zu treiben - wer weiß?. Wir haben ja jetzt schon mehr als genug davon, so daß zum Verkauf neuerer Produkte zuvörderst erstmal der Bedarf daran erzeugt werden muß. W.S.
W.S. schrieb: > Soll ich dir aufzählen, was in der Geschichte so alles weggeworfen > worden ist? Aber nicht, weil man aus Langeweile einfach mal so "alles neu macht der Mai" spielen wollte, das ist der Punkt. Pferdekutschen hat man nach und nach aufgegeben, weil das Auto schließlich praktikabler war und nicht, weil es innovativer war. Röhrenrechner hat man aufgegeben, weil Transistor-basierte Rechner nicht nur schneller, sondern auch Dimensionen sparsamer waren. Mit anderen Worten, Innovation ja, ABER sie muß auch einen Nutzen vorweisen, der das lohnenswert macht. Veränderung ist nur eine notwendige, aber keine hinreichende Bedingung für Fortschritt. Und wenn Du meinst, daß nicht der konkrete Quellcode nützlich ist: es steht Dir frei, z.B. den kompletten Linuxkernel von C nach Pascal zu portieren (oder nach was-weiß-ich). Scheint ja keine Kosten zu verursachen, also mach doch einfach mal. Insofern, doch, auch der konkrete Quellcode stellt geronnenen Wert dar. Insbesondere, wenn er nach Mannjahrhunderten nicht nur als Spielzeugalgorithmus besteht, sondern reifgetestet und debuggt wurde. Wollte man "from scratch" in einer "besseren Sprache" alles neu machen, wäre das nicht besser, sondern schlechter, weil dann neue Bugs drin wären, die auch wieder rausgetestet werden müßten. Netscape ist genau daran eingegangen, und das waren nicht die einzigen. Siehe auch Joel on Software dazu: http://www.joelonsoftware.com/articles/fog0000000069.html
Nop schrieb: > Und wenn Du meinst, daß nicht der konkrete Quellcode nützlich ist: es > steht Dir frei, z.B. den kompletten Linuxkernel von C nach Pascal zu > portieren (oder nach was-weiß-ich). Du hattest zwar vorhin Lisp genannt, aber für die hiesigen Fans strenger Logik hätte ich einen besseren Vorschlag: "Programmation en Logique" aka "Programmieren in Logik" aka Prolog. ;-) Das gab es sogar mal von Borland.
:
Bearbeitet durch User
W.S. schrieb: > Apropos: nicht der konkrete Quellcode ist wertvoll, sondern der Wert > steckt in den gefundenen Algorithmen und gewonnenen Erkenntnissen. Bis zu diesem Zitat hätte ich dir ja zumindest zugestanden, daß du doch auch etwas reale Erfahrung hast. Das war wohl ein Irrtum. Also doch nur ein reiner Theoretikus. Bevor die aber die ganze C-Software umschreibst, fang doch erst mal mit all den existierenden Fortran- und Cobolprogrammen an. Denn von der reinen Programmiersprachenlehre ist das doch alles noch viel mehr Aua. Oliver
:
Bearbeitet durch User
Nop schrieb: > Und wenn Du meinst, daß nicht der konkrete Quellcode nützlich ist: es > steht Dir frei, z.B. den kompletten Linuxkernel von C nach Pascal zu > portieren (oder nach was-weiß-ich). Pascal wurde schon vor langer langer Zeit von Wirth höchstpersönlich durch Modula-2 abgelöst. Und wenn man mal schaut, was denn der Nachfolger von Modula-2 ist, gelangt man am Ende seiner Nachforschungen bei Oberon. Auch da hatte Niklas Wirth seine Finger mit drin. Und siehe da: Oberon ist nicht nur eine praxisgerechte Programmiersprache, die nicht nur zu Lehrzwecken entwickelt wurde, sondern auch tauglich zur Entwicklung von Betriebssystemen: "Das ETH Oberon System ist ein eigenständiges Betriebssystem der ETH Zürich, das in der Sprache Oberon implementiert ist, als Entwicklungsgrundlage für die Sprache diente und ebenso wie der Compiler kostenlos erhältlich ist." Quelle: https://de.wikipedia.org/wiki/Oberon_(Programmiersprache%29 Also wenn, dann Oberon und nicht das angestaubte Pascal, bei welchem schon viel zu viele Frickler viel zu viele protprietäre Erweiterungen angeschflanscht haben, damit es überhaupt in der Praxis handhabbar wurde. @W.S. Statt dauernd enorme Energien darauf zu verschwenden, auf C zu schimpfen und es trotzdem angewidert zu verwenden, solltest Du besser etwas neues schaffen. Nicht lamentieren sondern Fakten schaffen! Solange man nur jammert, wird sich nichts ändern.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Statt dauernd enorme Energien darauf zu verschwenden, auf C zu schimpfen > und es trotzdem angewidert zu verwenden, solltest Du besser etwas neues > schaffen. Nicht lamentieren sondern Fakten schaffen! Solange man nur > jammert, wird sich nichts ändern. Auch wenn ich dir ansonsten zustimmen muss halte ich diesen Absatz für ein Totschlagargument. Ich kann auch etwas kritisieren ohne es selbst besser lösen zu können (egal wieso, sei es aus Mangel an Zeit, Geld, Infrastruktur, Wissen, Fähigkeiten). Wenn eine GUI (am besten eines OSS-Tools) sich unlogisch und fummelig verhält kann ich das kritisieren, auch wenn ich nur dummer Anfänger bin und von Programmieren keine Ahnung habe. Wenn unsre Obrigkeit keine Lösung für Atommüll erarbeiten kann sondern nur planlos hin- und herdiskutiert kann ich das kritisieren ohne selbst zu wissen was wir mit dem Zeug tun sollen, geschweigedenn eine Lösung initiieren oder umsetzen zu können. Mit "machs doch besser" kann man wunderbar jede Diskussion abwürgen, und ist sie auch noch so sinnfrei.
:
Bearbeitet durch User
Le X. schrieb: > Mit "machs doch besser" kann man wunderbar jede Diskussion abwürgen, und > ist sie auch noch so sinnfrei. Mag sein, aber W.S.' Gejammer bringt auch bloß keinen auch nur einen Millimeter weiter.
Jörg W. schrieb: > Mag sein, aber W.S.' Gejammer bringt auch bloß keinen auch nur einen > Millimeter weiter. Er hat ja zumindest im Ansatz recht. C hat Altlasten, C ist nicht für alles gut geeignet (GUI, Skripte zum Auswerten von Textdateien), C erfordert manchmal einfach ein akzeptieren, ein "ist halt so". Das hat aber auch garkeiner hier bestritten. Er zieht halt die falschen Schlüsse daraus, würde C gerne durch was inkompatibles Neues ersetzen. In 5 Jahren kommt dann der nächste, findet Kleinigkeiten und fordert wiederum eine neue Sprache. Drausen wo gearbeitet wird, wo Werte geschaffen werden gehts halt dreckig zu. Da muss man halt mal mit einer Lösung leben und gut ist. Wir sind hier nicht im Elfenbeinturm. Ich kenne auch Entwickler die ständig die 110%-Lösung wollen, die aber nie fertig wird und für den Kunden unbenutzbar ist.
Le X. schrieb: > Ich kann auch etwas kritisieren ohne es selbst besser lösen zu können Wenn Du aber etwas besseres willst und es selbst nicht kannst, dann musst Du halt jemanden dafür bezahlen, der es für Dich macht. Wenn man das auch nicht kann, dann ist es der denkbar schlechteste Weg, etwas besseres zu fordern aber keinen Finger dafür krumm machen zu wollen. Mit welchem Recht kann man etwas von anderen fordern, ohne sich selbst mit einzubringen - egal ob selbst oder zumindest monetär? Le X. schrieb: > Mit "machs doch besser" kann man wunderbar jede Diskussion abwürgen, [...] Unsinn. Man kann es besser machen, wenn man es tatsächlich braucht. Immer. Und Du kannst Dich auch nicht damit herausreden, dass W.S. zu dumm dafür sei. Ist er nämlich nicht. Aber das Gejammer geht mir ziemlich auf den Nerv. Stell Dir mal vor, wir lägen alle irgendwo wimmernd in der Ecke. Dann ginge nix mehr.
Le X. schrieb: > Ich kenne auch Entwickler die ständig die 110%-Lösung wollen, die aber > nie fertig wird und für den Kunden unbenutzbar ist. Eine Firma, die Software erst raus bringt, wenn der Entwickler sie als fertig ansieht, die macht Pleite. Deshalb gibt es z.B. lange vorher festgelegte Release-Zeitpunkte. Und da kommt raus, was man hat, nicht was man gerne hätte.
Frank M. schrieb: > Man kann es besser machen, wenn man es tatsächlich braucht. "Wenn man es braucht" ist wohl der knackpunkt. Kommt immer auf den Leidensdruck an. Wenn ich zuhause ein Tool benutze das sich unlogisch verhält schüttel ich den Kopf oder fluche kurz, arrangiere mich aber damit. Wenn in der Arbeit sowas nicht tut muss ich die Arschbacken zusammenkneifen und das Problem fixen, weil die Lösung am Schluß zuverlässig laufen muss. Bei W.S. ist wohl der Leidensdruck mittelmäsig. Er ist genervt genug zum Dauermeckern, hat aber nicht den Druck irgendwas ändern zu MÜSSEN. Das ist dann eine blöde Situation. ;-) Frank M. schrieb: > Unsinn. Ein Argument welches mit "Unsinn" beginnt sollte man eigentlich ignorieren wenn man nicht will dass der Thread ins Chaos abdriftet (siehe A&B Forum). Ich mach hier mal ne Ausnahme ;-)
Le X. schrieb: > Er zieht halt die falschen Schlüsse daraus, würde C gerne durch was > inkompatibles Neues ersetzen. Warum tut er das dann nicht? Selbst wenn er es nicht persönlich kann, kann man doch wenigstens die verbersserten Ansätze der Sprache D (als Nachfolger von C) beschreiben und dokumentieren. Wenn man dafür Leute begeistern kann, wird man auch ein Team schaffen, die diese Ideen auch umsetzen. Ich persönlich war 2000 auch davon genervt, dass immer nur einer in der Familie über DSL surfen konnte, weil damals das dumme DSL-Modem ohne Router-Eigentschaften direkt in den PC gesteckt werden musste. Aber statt mich darüber aufzuregen und öffentlich rumzujammern, habe ich damals eine Router-Lösung geschaffen, die auf einem ausgedienten PC mit einer einzelnen 1,44MB-Diskette lief. Daraus wurde dann fli4l, der erste massentaugliche Homerouter mit einigen hunderttausend Anwendern. Auch der längste Weg beginnt mit dem ersten Schritt. (Konfuzius)
A. K. schrieb: > Eine Firma, die Software erst raus bringt, wenn der Entwickler sie als > fertig ansieht, die macht Pleite. Deshalb gibt es z.B. lange vorher > festgelegte Release-Zeitpunkte. Und da kommt raus, was man hat, nicht > was man gerne hätte. Eben. Oder anders ausgedrückt: man muss sich mit dem arrangieren was man hat, z.B. mit der Programmiersprache C. Die Dauersuche nach der akademischen Musterlösung ist nicht wirtschaftlich.
Frank M. schrieb: > Warum tut er das dann nicht? Selbst wenn er es nicht persönlich kann, > kann man doch wenigstens die verbersserten Ansätze der Sprache D (als > Nachfolger von C) beschreiben und dokumentieren. Eine Sprache, die auf eine einzige Person zurück geht: Walter Bright, dem PCs auch den ersten nativen C++ Compiler verdanken. Er hatte Ideen und realisierte sie, dabei Kompatibilität zu C über Bord werfend. Weshalb das auch D heisst, und nicht C(Version20xx). > Daraus wurde dann fli4l, der erste > massentaugliche Homerouter mit einigen hunderttausend Anwendern. Dafür nachträglich ein dickes Dankeschön.
:
Bearbeitet durch User
A. K. schrieb: > Weshalb das auch D heisst, und nicht C(Version20xx). Mift. Also ist der Name D schon belegt. Mit unserer eigens neu zu schaffenden Programmiersprache müssen wir uns also zwischen C und D quetschen. C++ ist ebenso schon belegt, bleibt also noch D-- übrig :-)
Frank M. schrieb: > Auch der längste Weg beginnt mit dem ersten Schritt. Da wir gerade von unsinnigem Hin-und-Her-Argumentationen zu Anekdoten übergehen. ;-) Ging mir damals ähnlich, aber noch vor DSL, mit ISDN. Hellmuth Michaelis hatte zwar für *BSD eine schöne ISDN-Suite, aber er hatte keinen Leidensdruck, darüber PPP fahren zu müssen, daher stand das nicht auf seiner Agenda. Ich habe mir dann eine angefrühstückte SyncPPP-Implementierung, die schon im FreeBSD vorhanden war, aber die nicht für Wählverbindungen konzipiert waren (kennt jemand heute noch Standleitungen mit Bitstrom-Protokollen? ;-) genommen, mir die PPP-RFCs dazu geschnappt, und implementiert, was man implementieren musste (dabei die Qualität dieser RFCs schätzen gelernt). Zurück zu obiger Argumentation: ich hätte mich stattdessen auch hinstellen können, und Hellmuth damit nerven, dass das von ihm lediglich vorgesehene simple Cisco-lastige raw protocol doch sowas von K*cke ist, dass man da was moderneres braucht, dass ich damit nicht leben kann, etc. pp. Vermutlich hätte ich aber auch ein Jahr später noch keine benutzbare Lösung gehabt. :-) (Mir ist so, als würde NetBSD „meine“ Implementierung nach wie vor für PPP-over-Ethernet benutzen. Kann mich aber irren, habe da lange nicht mehr reingesehen.)
Jörg W. schrieb: > kennt jemand heute noch Standleitungen mit Bitstrom-Protokollen? ;-) SDLC/HDLC? Das bildet die Basis des D-Kanal-Protokolls von ISDN.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.