Programmier-"Niveau"
-
Xin schrieb:
Also bestätige ich Dir hiermit den Einzelkämpfer.
Ein Einzelkämpfer ist nicht daran interessiert mit anderen zu diskutieren.
QFT
-
Dieser Thread beweist doch sehr gut, daß die Ausgangsthese stimmt:
cooky451 schrieb:
mir fällt immer mehr auf, dass meine Vorstellung von "programmieren können" und die von den meisten anderen ziemlich weit auseinander geht
Jeder sieht nur seine Sicht der Dinge...
-
Shade Of Mine schrieb:
Xin schrieb:
Also bestätige ich Dir hiermit den Einzelkämpfer.
Ein Einzelkämpfer ist nicht daran interessiert mit anderen zu diskutieren.
QFT
Hey, Shade... wir sind auf Seite
78... das war ein EigentorThanks for playing... :->
-
Kindergarten. Habt ihr nichts zu tun? Hier jemals wieder auf eine sachliche Diskussion zurückzukommen ist doch geradezu ausgeschlossen. Die Möglichkeit dessen scheint mir nur eine Ausflucht zu sein diesen Blödsinn fortzuführen.
Aber anscheinend habt ihr ja Spaß dran.
-
Eisflamme schrieb:
Hier jemals wieder auf eine sachliche Diskussion zurückzukommen ist doch geradezu ausgeschlossen.
You're right.
Hierum geht's:
cooky451 schrieb:
Hi,
mir fällt immer mehr auf, dass meine Vorstellung von "programmieren können" und die von den meisten anderen ziemlich weit auseinander geht. In meinem Umfeld interessiert sich eigentlich niemand wirklich für den Standard, Patterns, etc. Das bleibt größtenteils auch so bei Studenten in höheren Semestern, und viele Profs oder Angestellte die sich mit so etwas beschäftigen scheint es auch nicht zu geben. "Programmieren können" scheint im Allgemeinen zu heißen, dass man if/while/for schon mal gesehen, und irgendeine vage Vorstellung davon hat, was OOP bedeutet. Und private ist toll, warum kann zwar niemand wirklich erklären, aber das macht man halt so. Und da hört dann das Wissen (und Interesse) der meisten mir bekannten Programmierer irgendwie schon auf. Dinge wie Exception Safety hören viele zum ersten mal, bei Templates schaffen ein paar es gerade noch <typename T> zu benutzen. Das klingt jetzt alles sehr negativ fällt mir gerade auf, aber darum soll es gar nicht gehen. Mich würde viel mehr einfach mal interessieren, wie viele Leute in eurem Umfeld schon mal MVC gehört haben, simple TMP Programme schreiben können, wissen was RAII ist, wie ein GC etwa funktioniert, sich mehr oder weniger im C++ (oder C) Standard zurecht finden, überhaupt in der lage sind Exception sichere Programme schreiben zu können, ...
Denn die einzigen Leute von denen ich weiß, dass sie diese Kriterien erfüllen, "kenne" ich sozusagen aus dem Internet, und selbst da sind die rar.
-
Och ja, ich hab ja am Anfang ein paar brauchbare Antworten bekommen, streitet euch mal ruhig über den Quatsch, ist doch lustig. Aber könnte mich eben jemand auf den neuesten Stand bringen, ich habe irgendwie den Faden verloren. Irgendwas mit Stack gehört zu RAII oder nicht oder so.
-
Xin schrieb:
hustbaer schrieb:
Und nochwas: du redest hier (wenn du mit mir redest) nicht mit einem Vollidioten. Ich habe eine sehr genaue Vorstellung davon was Compiler so machen, wie der übersetzte Code so aussieht etc. Und auch eine halbwegs gut davon was verschiedene Compiler so für Optimierungen durchführen können. Das "aus 3 mach 2" Beispiel ist z.B. keineswegs erfunden.
Die Variable wird nie im Registerlanden, sondern das Objekt, dass die Variable identifiziert.
Nehmen wir "i". Behaupten wir, dass "i" auf dem Stack bei -4 liegt. Das Objekt, dass mit "i" identifiziert werden soll, hat also das Offset -4 zum Stack und heißt im Quelltext eben "i". Das ist Deine Variable.
Die Optimierung greift. Sie lädt das Objekt, welches sich 4 Bytes vor dem Stackpointer befindet als 32 Bit Datenwert in das Register und iteriert über das Register.Nur dass
i
überhaupt nirgends mehr existiert. Es existiert dann lediglich der Wert des Ausrducks&p[i]
in einem Register (das ist die neue Variablep2
in meinem Beispiel). Es gibt im optimierten Programm *nichts* mehr dasi
entspricht, keine einzige Speicherstelle/Register/... wo also z.B. 23 drinstehen würde wenn die Schleife sich im Durchlaufi == 23
befindet.Dafür gibt es ein neues "Ding" das im Source-Code keinen Namen hat: den Ausdruck
&p[i]
.Ich hab' dazu mal eine halbwegs high-level gehaltene Beschreibung des LLVM Optimizers/Code-Generators gelesen (hab leider keinen Link mehr dazu parat, falls jmd. die Beschreibung kennt... würde ich selber gerne nochmal lesen). Vorausgesetzt ich hab das richtig verstanden, dann macht der LLVM...
a) Primär erstmal Register-Allocation mit virtuellen Registern, von denen es beliebig viele gibt. Aus diesen virtuellen Registern macht dann der Code-Generator Code der mit echten Registern und/oder Stack arbeitet - wie es halt gerade passt.
b) Die Register-Allocation wird nicht nur für Variablen gemacht, sondern für sämtliche Zwischenergebnisse.
Und dann wird weggeworfen was weggeworfen werden kann.
Dadurch kann es leicht sein dass für ein Codestück weder die Variable "a" noch die Variable "b" übrigbleiben, der Ausdruck "a+b" überlebt aber.c) Wenn es eine Zuweisung im Code gibt, dann wird für den neuen Inhalt der Variable nach Programmstelle X eine neue Register-Allocation gemacht. D.h. selbst wenn die Variable "a" übrig bleibt kann es sein dass sie munter verschiedene Register durchwandert, vielleicht sogar zwischendurch mal auf dem Stack landet etc. Oft wird das keinen Sinn machen, und der generierte Code wird genau ein Register für eine Variable verwenden. Manchmal macht es aber Sinn, nämlich z.B. wenn der Code-Generator out-of-order Code generiert, und daher einen alten Wert einer Variable braucht nachdem diese bereits modifiziert wurde.
Und sogesehen halte ich es für sehr irreführend zu sagen dass eine Variable einem Offset/einer Adresse/einem Register entspricht.
Weil es eben nur bestimmte Spezialfälle sind wo man eine solche Zuordnung sinnvoll herstellen kann.Man kann von mir aus gerne sagen dass es "oft" so ist, z.B. wenn man einem Anfänger erklären will was da so ca. ungefähr passiert, aber als absolutes Statement ist es für mich halt einfach falsch.
Xin schrieb:
Die For-Schleife erlaubt nicht die Entfernung des Objektes, sie erlaubt aber, dass i nie auf dem Stack angelegt werden muss, in dem sofort das Register mit 0 initialisiert wird. Die Variable i muss kein Objekt auf dem Stack identifizieren und auch keine statische Adresse. Hier muss sie das Register addressieren, dass durch die Optimierung statt der stackrelativen Position ausgewählt wurde.
Hier wird nichts rausoptimiert, hier wird nur in die CPU verlagert.Siehe oben.
Wie kann die Variablei
ein Register adressieren (oder eine wie auch immer geartete Sache wo man einen Wert abspeichern kann), wenn es *nichts* mehr im gesamten Computer gibt wo der Wert abgespeichert wäre der ini
stehen würde/sollte/müsste?
Gleichzeitig ist die Variablei
auch nicht vollständig entfernt worden, denn sie kann nunmal einfach nicht vollständig entfernt werden. Dafür hat der Compiler das mit Hilfe der Variablei
beschriebene verhalten anders umgesetzt: er hat die neuen "Variablen" (Ausdrücke, Register, ... wie auch immer man es nennen will)&p[i]
und&p[len]
eingeführt.Xin schrieb:
Nach dem Compilervorgang ist die Variable komplett weg, das Objekt, das mit 'i' identifiziert wurde, existiert weiterhin im Register.
Ich wiederhole mich jetzt, aber egal...
Das miti
identifizierte Objekt ist vollkommen weg, übrig bleiben nur neue Dinge die das vom Programm beschriebene Verhalten umsetzen.
Der Compiler verwendet hier das was unter C++lern gern als "as-if rule" bezeichnet wird: das beobachtbare Verhalten des Programms muss genau das selbe sein wie wenn ("as if") das originale Programm ausgeführt würde. Die Beibehaltung irgendwelcher nicht beobachtbaren Konstrukte wie z.B. die "direkte" Umsetzung lokaler Variablen ist nicht vorgeschrieben. Und daher erzeugen Compiler auch gerne mal Code wo es keine direkte Entsprechung zu lokalen Variablen mehr gibt.
(Die "as-if" Regel findet man vermutlich auch in den meisten anderen Sprachen, ich beziehe mir hier nur auf C++ da ich sie von C++ her kenne und mich mit anderen Sprachen wesentlich weniger gut auskenne).Falls Du doch fachlich(!) mit mir diskutieren möchtest, dann gerne, aber nicht hier.
Sondern lieber wo?
Wir können das auch gerne per Email fortsetzen falls dir das lieber wäre. Oder einen neuen Thread aufmachen - nur dass dort dann sofort wieder 27 andere Leute mitposten würden, würde also vermutlich nix bringen.ps: natürlich *kann* ein Compiler so arbeiten dass es (abgesehen von Fällen wo etwas komplett wegoptimiert wird) immer eine 1:1 Zuordnung Variable <-> Adresse/Offset/Register gibt. Er *muss* aber nicht, und Compiler die richtig gut optimierten Code erzeugen können das mMn. auch nichtmal. Weil sich durch diese Einschränkung eben einfach zu viele Optimierungsmöglichkeiten verbieten würden.
-
hustbaer schrieb:
Und sogesehen halte ich es für sehr irreführend zu sagen dass eine Variable einem Offset/einer Adresse/einem Register entspricht. ...
Man kann von mir aus gerne sagen dass es "oft" so ist, z.B. wenn man einem Anfänger erklären will was da so ca. ungefähr passiert, aber als absolutes Statement ist es für mich halt einfach falsch.
Ich kürze das mal ein wenig ab, um dieses Topic in diesem Thread mal zu einem Ende zu bewegen...
Die Optimierung von Maschinencode ist ungefähr das letzte, was man einem Anfänger erklärt. Und man erklärt sie auch nicht, damit ich Shade begreiflich machen kann, dass ich RAII und die Programmierung allgemein aus einer ganz anderen Perspektive betrachte als ein Anwendungsentwickler.
Mein Statement über Variablen gilt auch nicht für die Nachverarbeitung durch einen Maschinencode-Optimierer, sondern ganz allgemein. i ist auch eine Objekt und eine Variable(=Objektidentifizierer), wenn es nie benutzt wird.
Was daraus wird, wenn der Maschinencode durch den Fleischwolf gedreht wird, das ist eine ganz andere Frage - hier findet quasi ein neuer Compiliervorgang statt, der nur noch mit Objekten abläuft und vollkommen ohne ein Dictionary, wie welches Objekt für den Anwendungsentwickler mal geheißen hat. Und das ist vor allem eine Frage, die überhaupt nichts mit dem ursprünglichen Topic zu tun hat. Wenn ich also hier keine vollständige Abhandlung in allein Einzelheiten schreibe, die die Registerverteilung bei der Maschinenspracheoptimierung beinhaltet, dann liegt das auch daran, dass das hier einfach nicht das Thema ist. Und ein Anfänger hat sich eventuell schon bei RAII verabschiedet, was auch nicht das Thema hier war. Da wurde genauso detailverliebt jedes Bit angesehen, weil ich RAII als Buzzword bezeichnet habe für Objekte, deren Speichermanagement durch den Stack gemanagt werden.
Ich bin genauso detailverliebt, denn ich implementiere derartige Details und lasse mich dann leider auch zu gerne dazu hinreißen nach möglicherweise unverstanden oder schlecht verstandenen Details zu forschen. Aber das alles hat nichts in diesem Thread zu suchen oder wäre auch nur annähernd etwas, was jemand, der nicht wirklich scheiße tief in der Materie steckt noch interessiert.An dem Link wäre ich unabhängig von diesem Thread allerdings auch interessiert, falls Du ihn wiederfindest... ^^ (PN?)
Das wäre nämlich genau meine Materie. ^^hustbaer schrieb:
Wir können das auch gerne per Email fortsetzen falls dir das lieber wäre.
Mail klingt gut.
-
Wenn ihr nicht bald aufhört, werde ich absofort dich, hustbaer, Keuchhusten oder Raucherhusten nennen und dich Xin, "nix" oder "niX" (deinen Namen von hinten nach vorne gelesen)!
-
Steffo schrieb:
Wenn ihr nicht bald aufhört, werde ich absofort dich, hustbaer, Keuchhusten oder Raucherhusten nennen und dich Xin, "nix" oder "niX" (deinen Namen von hinten nach vorne gelesen)!
Wieso sind doch lebendes Beispiel für das Programmierer-Niveau.
-
Zeus schrieb:
Wieso sind doch lebendes Beispiel für das Programmierer-Niveau.
Genau. Alleine die Tatsache, dass sie sich so lange über so einen Kleinkram unterhalten können, zeigt schon, dass beide ein hinreichendes Interesse an sauberen Definitionen und Code haben, und das qualifiziert beide zu zumindest potentiell guten Programmierern.
-
cooky451 schrieb:
Zeus schrieb:
Wieso sind doch lebendes Beispiel für das Programmierer-Niveau.
Genau. Alleine die Tatsache, dass sie sich so lange über so einen Kleinkram unterhalten können, zeigt schon, dass beide ein hinreichendes Interesse an sauberen Definitionen und Code haben, und das qualifiziert beide zu zumindest potentiell guten Programmierern.
Ich bin nicht sicher, ob das ein Kompliment ist, aber ich befürchte, Du hast unabhängig davon Recht. ;-D
-
Xin schrieb:
Und man erklärt sie auch nicht, damit ich Shade begreiflich machen kann, dass ich RAII und die Programmierung allgemein aus einer ganz anderen Perspektive betrachte als ein Anwendungsentwickler.
Ja, du hast eine sehr einzigartige Sicht auf alle Dinge.
zB diese Diskussion - eine Variable als Highlevel Konzept lehnst du ab, als Lowlevel Konzept ebenfalls. Eine Variable ist ein Mischding das mal da ist und mal nicht, aber doch irgendwie immer ein Offset auch wenn es sie garnicht gibt.
Ich wette es gibt keinen 2. Menschen auf der Erde der das gleich sieht.
-
Shade Of Mine schrieb:
Ja, du hast eine sehr einzigartige Sicht auf alle Dinge.
...
Ich wette es gibt keinen 2. Menschen auf der Erde der das gleich sieht.Die Wette würdest Du verlieren und deine Zusammenfassung, die ich eines Quote nicht wert ist, spricht für sich.
-
Offtopic: (Ah ne, das war ja quasi das eigentliche Thema.)
In meiner heutigen Java Übungsaufgabe an der Uni habe ich eine Vorlage bekommen, in der sie den Kontostand von Personen als double modelliert haben. Sehr geil.
-
cooky451 schrieb:
Offtopic: (Ah ne, das war ja quasi das eigentliche Thema.)
In meiner heutigen Java Übungsaufgabe an der Uni habe ich eine Vorlage bekommen, in der sie den Kontostand von Personen als double modelliert haben. Sehr geil.Uns versuchte man damals im ersten Semester die Idee von Klassen beizubringen, in dem man uns erklärte, wie man reelle Zahlen abbilden könnte. Dafür wurden Vorschläge gesammelt: Zähler und Nenner und diverses andere. Der Prof entschied sich für die ungeschickteste Lösung, die er selbst vorgeschlagen hat: Nämlich mit zwei Integern, die den Bereich vor dem Komma und den Bereich nach dem Komma repräsentieren.
ReelleZahl( int vorKomma, int nachKomma )
Ich stellte dann die Frage, wie dann Zahlen wie 1,01 erzeugt werden und was passiert, wenn Zahlen wie 1,1 und 1,12 addiert werden. Im Verlauf der Vorlesung wurden die Sätze immer länger und verschachtelter: Unter der Bedingung, dass die es nicht zum Zahlen beide die gleiche Anzahl von Nachkommastellen haben, die auch konstruierbar sind, die auch keinen Überlauf erzeugen, wenn man sie addiert (1,5 + 1,5 ergibt ja bekanntlich 2,10), dann gilt.... (irgendwas triviales wie dass das Ergebnis stimmt). In solchen Sätzen ging dann die ganze Vorlesung weiter, bis man zu dem Schluss kam, dass man die heutige Vorlesung besser vergessen sollte.
-
@Xin: Das ist ein gutes Beispiel für rationale Zahlen. Da kommt dann auch kein 1,00001 vor. Überlauf kann man teilweise verhindern, wenn man den größten gemeinsamen Teiler findet und wenn in deiner rationalen Klasse 1,5 + 1,5 = 2,1 rauskommt, dann hast du sie eben schlicht falsch implementiert...
-
Naja, theoretisch könnte man das dann ja verkaufen als Lektion warum es wichtig ist die Daten richtig zu modellieren.
Denn oft kann Code enorm viel besser werden, indem die Datenstruktur besser gewählt werden... Aber das hat der Prof da dann wohl auch nicht verstanden gehabt :p
-
Steffo:
Ich versteh kein Wort. 1. hat Xin von reellen Zahlen gesprochen und 2. ist z.B. 1,00001 sehr wohl eine rationale Zahl, also was willst Du jetzt sagen?
-
Eisflamme schrieb:
Steffo:
Ich versteh kein Wort.Weil du mich nicht verstehen willst.