Seite 2 von 5

Verfasst: 23.04.2009 01:30
von ZeHa
Na gut, dann stellen wir uns mal vor, es gäbe unter PB keine Enumerations. Und irgendeiner würde jetzt aus C++ vorschwärmen, daß es da welche gibt und daß die unheimlich sinnvoll sind. Und dann würdest Du jetzt sagen:

Wie ich sagte, in meinen Augen ist das wieder so ein "Feature" das niemand braucht. Denn es gibt real nunmal nur Zahlen. Genau wie es schon immer in PB war. Und es wurden in all den Jahren auch sicher große Projekte geschrieben und auch bestimmt mit mehr als mit einer Person. Vermisst irgendjemand dieses Feature? Nein. Hat es uns geschadet oder unsere Produktivität eingeschränkt? Ebenfalls nein.

Das kann man beliebig fortführen. Es gibt immer Features, die man selbst noch nie eingesetzt hat bzw. in der verwendeten Sprache nicht vorhanden sind, und die man deshalb für überflüssig empfindet, nur weil man den wahren Nutzen noch nie erfahren durfte (und mit "erfahren" meine ich tatsächlich "erfahren", nicht einfach nur "mal gelesen haben wozu das gut sein soll" oder dergleichen).
Sprichst aus Erfahrung wa'? <)
Ich bin von Beruf Software-Entwickler.

Verfasst: 23.04.2009 01:31
von ZeHa
Kaeru Gaman hat geschrieben:bei bla.hWnd sieht man das später im kot nicht mehr.
Doch, einer wird es sehen: der Compiler.
Nur leider nicht der PB-Compiler.

Verfasst: 23.04.2009 01:51
von Kaeru Gaman
> Es gibt immer Features, die man selbst noch nie eingesetzt hat bzw. in der verwendeten Sprache nicht vorhanden sind, und die man deshalb für überflüssig empfindet, nur weil man den wahren Nutzen noch nie erfahren durfte

das ist ja durchaus ein Argument.
als zusätzliche abschaltbare Feature wäre das vielleicht ne Sache, sowas wie EnableExtendedTypes...

aber im Endeffekt ist es doch mehr oder weniger kosmetisch, und es gibt so viel wichtigeres was noch getan werden muss...

Verfasst: 23.04.2009 09:38
von alter Mann
@FluidByte : meiner Meinung nach hast Du die Dereferenzierung vergessen

Code: Alles auswählen

Procedure SomeFunction (buffer,srcFrame)

  If buffer=0 : ProcedureReturn 1 : EndIf

  buffer = PokeI(buffer+4)
  buffer = PokeI(buffer+(4*srcFrame))

  srcSurf.IDirectDrawSurface7 = #Null
  srcSurf = PokeI(buffer+12) 
 ....

Verfasst: 23.04.2009 10:28
von ZeHa
Kaeru Gaman hat geschrieben:aber im Endeffekt ist es doch mehr oder weniger kosmetisch, und es gibt so viel wichtigeres was noch getan werden muss...
Ich halte das ehrlich gesagt nicht für kosmetisch, es sorgt einfach für sichereren Code, wenn der Compiler erkennt, daß Du etwas tust, was eigentlich nicht in Ordnung ist.

Als Beispiel mal ein kleiner PB-Code:

Code: Alles auswählen

Structure TEST
    name$
    id.l
EndStructure

Structure FEST
    x.l
    y.l
    name$
EndStructure

Procedure theProc(*obj.FEST)
    MessageRequester("name$", *obj\name$)
    MessageRequester("x", Str(*obj\x))
    MessageRequester("y", Str(*obj\y))
EndProcedure

something.TEST
something\name$ = "something"
theProc(something)
Wie Du siehst, wird hier in der Procedure eine Variable vom Typ "FEST" erwartet, aber es wird einen vom Typ "TEST" übergeben. Der Compiler meckert nicht. Du kannst das Programm sogar ausführen, es wird zwar seltsame Werte ausgeben, aber viel Spaß dann bei der Fehlersuche. Vor allem, wenn das Projekt sehr groß ist und mehrere Leute dran gearbeitet haben! Und was die Sache bzgl. PB noch krasser macht, ist, daß es hier nichtmal um einen simplen Datentyp geht, der einfach nur ein Alias hat, sondern hier geht es sogar um zwei Strukturen!

Der C/C++ Compiler würde dagegen sofort meckern. Selbst wenn beide Variablen einfache Integer wären, die einfach nur per Typedef zu verschiedenen Typen gemacht wurden (also genau das, worum es bei Fluids Kommentaren ging), würde der Compiler zumindest eine Warning ausgeben.

Das heißt, Du würdest eine solche potenzielle Fehlerquelle sehr schnell entdecken, am besten noch bevor Du überhaupt was vom Fehler mitkriegst (weil Du ja die Warnings siehst und die Stellen direkt in Ordnung bringen kannst, bevor Du das Programm testest).

Und nun kann es ja sein, daß jemand so etwas absichtlich machen möchte. Zum Beispiel, wenn es sich wirklich nur um simple Datentypen handelt. In diesem Fall kann er casten, und das ist der Grund, warum in dem C++ Codebeispiel so viele Klammern sind. Weil explizit gesagt wird "Hallo Compiler, ich will hier gern ein HWND an eine Funktion übergeben, die eigentlich einen unsigned int verlangt. Ich weiß was ich tue, also werde ich hier casten, Du weißt also Bescheid."
Somit wird der Compiler auch keine Warning mehr ausgeben. Aber der Programmierer muß eben ausdrücklich vermerken, daß dieser Cast gewollt ist.

Ihr müßt bei einem großen Projekt auch immer im Hinterkopf behalten, daß es sehr gut sein kann, daß ein Fehler nicht von dem Programmierer bemerkt wird, der ihn verursacht hat, sondern von einem anderen aus dem Team, der gar nicht weiß, woran der Verursacher gerade gefummelt hat. Wenn er nun das Projekt kompiliert, und der Compiler ihm gleich mal ein paar Warnings um die Ohren haut, dann hat er wenigstens schonmal einen gewaltigen Vorteil beim Debuggen. Wenn aber alles scheinbar super kompiliert, dann weiß er beim Entdecken der Fehlfunktion erstmal nicht, ob es sich um solch einen Programmierfehler handelt, oder ob es z.B. eher ein logischer Fehler ist (z.B. daß irgendeine Berechnungsformel falsch ist oder daß bestimmte Funktionen nie oder in falscher Reihenfolge aufgerufen werden).

Es gibt nunmal Fehler, die gleich beim Kompilieren erkannt werden können, und das sollten sie auch, denn Laufzeitfehler sind oft schwer zu finden. Ihr beschwert euch ja auch nicht drüber, daß PB meckert, wenn man eine undeklarierte Konstante verwendet. Man könnte ja auch sagen "so ein Quatsch, dann soll er die halt einfach mit 0 vorbelegen."

Zu guter Letzt: Ich sage ja nicht, daß PB das unbedingt braucht. Ich finde es nur nicht okay, zu sagen, daß das völlig überflüssig ist, nur um mal wieder C++ in ein schlechtes Licht zu rücken ("da gibt's ja für jeden Scheiß Klammern").
EDIT: Aber daß PB im obigen Beispiel stillschweigend kompiliert, das finde ich schon sehr bedenklich. Typedefs hin oder her, das da oben ist eigentlich ein höchst fragwürdiges Verhalten.

Verfasst: 23.04.2009 11:21
von Kaeru Gaman
> Wie Du siehst, wird hier in der Procedure eine Variable vom Typ "FEST" erwartet, aber es wird einen vom Typ "TEST" übergeben.

du übergibst zwei identische typen, zwei pointer,
die du nur mit unterschiedlichen virtuellen Zusatzoffsets für den Speicherzugriff versiehst.

wenn man solche structs auch noch so benennt, dass eine Verwechslung vorprogrammiert ist, gehört erstmal der Teamkoordinator gefeuert.

PB ist eine Low-Level Sprache, die dir einige Kniffe und Tricks erlaubt.

mit einer Compilerwarning würde ich leben können, aber wenn der Compiler sich bei tausenderlei Trickserei auf einmal weigern würde, hätte ich bestimmt nicht als einziger nen Hals.

und es gibt tonnenweise wichtigerer Probleme...

Verfasst: 23.04.2009 11:30
von ZeHa
Unter C++ sind aber zwei Pointer auf unterschiedliche Typen niemals identisch, und genau das ist es, was so sinnvoll ist. Wenn ich einen Pointer auf eine Float übergebe oder einen Pointer auf eine TEST-Struktur, dann sind das einfach zwei völlig verschiedene Dinge.

Genauso wie wenn Du Dein Auto mit Benzin oder Diesel tankst. Du merkst leider erst zur Laufzeit, ob das nun richtig oder falsch war, und dann viel Spaß ;)
Hätte der Zapfhahn für Diesel dagegen die Form eines Vierkantrohres, dann würdest Du bereits zur "Compile Time" gewarnt werden. Und wenn Du es doch tun willst, dann könntest Du immer noch einen Adapter draufsetzen (also "casten").

Wenn ein String erwartet wird (also ein Pointer!) und Du einen Pointer auf irgendwas völlig anderes übergibst, dann meckert PB doch auch. Finde ich nicht grad verkehrt ;)

Verfasst: 23.04.2009 11:41
von Kaeru Gaman
ich habe auch nicht gesagt, dass ich es verkehrt finde.

ich empfinde es nur zum jetzigen zeitpunkt als nicht notwendig.
ebenso müßig wie diese diskussion.

kannst es ja mal in die Feature Requests schreiben.
muss Fred eh selber entscheiden, welche Priorität er dem zumessen will.

Verfasst: 23.04.2009 12:10
von ZeHa
Naja wie ich bereits sagte, ich bin nicht der Meinung, daß PB so einen Check unbedingt braucht, oder daß man Typedefs machen kann. Es wäre zwar schön, aber es ist nicht notwendig. Mir ging es nur darum, klarzustellen, daß solch eine Funktion bei weitem nicht "völlig überflüssig" ist, sondern durchaus sehr sinnvoll ist und in einer "Industrie-Sprache" wie C++ absolut nicht fehlen darf. PB als Nischensprache für Einzelkämpfer oder kleine Teams muß sowas nicht unbedingt haben, vielleicht wäre es auch für die Anfänger zu kompliziert.

Nicht jede Sprache muß alles können und für jeden Bereich einsetzbar sein. Aber man sollte halt deshalb nicht gleich alles als total unnütz hinstellen, was es in anderen Sprachen gibt und bei der ersten Betrachtung vielleicht etwas komplizierter erscheint.

Verfasst: 23.04.2009 14:33
von Fluid Byte
ZeHa hat geschrieben:Na gut, dann stellen wir uns mal vor, es gäbe unter PB keine Enumerations. Und irgendeiner würde jetzt aus C++ vorschwärmen, daß es da welche gibt und daß die unheimlich sinnvoll sind. Und dann würdest Du jetzt sagen:

Wie ich sagte, in meinen Augen ist das wieder so ein "Feature" das niemand braucht. Denn es gibt real nunmal nur Zahlen.
Der Vergleich hinkt so sehr das wenn man ihn personifizieren müsste nur davon ausgehen kann das ihm beide Beine einzementiert wurden. Ich meine wie kommst du auf Enumerations?
ZeHa hat geschrieben:Das kann man beliebig fortführen. Es gibt immer Features, die man selbst noch nie eingesetzt hat bzw. in der verwendeten Sprache nicht vorhanden sind, und die man deshalb für überflüssig empfindet, nur weil man den wahren Nutzen noch nie erfahren durfte (und mit "erfahren" meine ich tatsächlich "erfahren", nicht einfach nur "mal gelesen haben wozu das gut sein soll" oder dergleichen).
Heiß ich "JENS"? Steht da irgendwo "Zlatko" auf meiner Stirn? Es nie besonderes clever Aussagen auf Basis von Vermutungen anzustellen.
ZeHa hat geschrieben:Ich bin von Beruf Software-Entwickler.
Schnucki, das bin ich auch. :lol:

Das bezog sich eher auf "20+ Leute" und "50000+ Zeilen." Falls du mal in solch einer Größenordnung gearbeitet hast gibt es doch sicher 2 oder 3 konkrete Beispiele bzw. Situationen die den angeblichen Vorteil dieses "Features" verdeutlichen.
ZeHa hat geschrieben:Wie Du siehst, wird hier in der Procedure eine Variable vom Typ "FEST" erwartet, aber es wird einen vom Typ "TEST" übergeben. Der Compiler meckert nicht.
Ich meine der erste Vergleich war schon hart an der Grenze aber du kommst mir doch jetzt nicht damit oder? Ein Test-Fest oder was? Das was du anbringst widersprichst sich mit dem "20+ Leute" / "50000+ Zeilen" Kommentar. Professionelle Programmierer in großen Teams die mit langen Quelltexten arbeiten benennen ihre Strukturen wohl kaum in dieser Art und Weise. Außerdem geht es fast nie um Namensverwechselung sondern darum das man sich mal verschreibt. Dafür allerdings gibt es EnableExplcit.

Zum Kernproblem:

Typendeklarationen mit dem gleichen Basistyp sind nichts weiter als Betrug am Kuden. Nehmen wir bspw. den API-Befehl 'SendMessage'. Dank dieses "Features" haben wir nun sage und schreibe 4 (!) verschiedene Variablentypen: HWND, UINT, WPARAM und LPARAM.

Diese basieren aber alle auf LONG :!:

Ginge es ausschließlich um strukturierte Variablen dann könnte ich das vielleicht bis zu einem gewissen Grad nachvollziehen. Aber so, keine Chance.
ZeHa hat geschrieben:Nicht jede Sprache muß alles können und für jeden Bereich einsetzbar sein. Aber man sollte halt deshalb nicht gleich alles als total unnütz hinstellen
Nicht "total unnütz", nur überflüssig.

PS: Ich weiß das hier alles ist Haarspalterei Deluxe (auf beiden Seiten) und ich möchte eigentlich nicht das wir uns deswegen "in die Wolle" kriegen. <)