Ohne Nil prüfen ob Objekt erstellt wurde.

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von BeniBela »

Code: Alles auswählen

 
if not assigned(fMyIntf) then fMyIntf := TIrgendWas.create; 
Der record Nutzer ist dafür verantwortlich es auf nil zu setzen

Das größere Problem könnte die Freigabe sein

Benutzeravatar
theo
Beiträge: 10874
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

BeniBela hat geschrieben:

Code: Alles auswählen

 
if not assigned(fMyIntf) then fMyIntf := TIrgendWas.create; 
Der record Nutzer ist dafür verantwortlich es auf nil zu setzen

Das größere Problem könnte die Freigabe sein
Nö, der Record Nutzer soll sich darum eben nicht kümmern müssen.
Die Freigabe sollte OK sein, deshalb ja das Interface, wegen dem Referenzzähler.

Eine Möglichkeit habe ich mir überlegt. Man könnte eine QWord Kontrollvariable mitführen und diese nach dem Createn auf einen bestimmten konstanten Wert setzen.
Vorher kann man diese Variable gegen die Konstante prüfen. Dass die Variable zufällig diesen einen, bestimmten Anfangswert bekommt, ist extrem unwahrscheinlich.

BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von BeniBela »

Ich habe mal ein paar Funktionen durchprobiert (unter 2.6):

Die Initialisierung erfolgt mit der Funktion fpc_initialize. Danach ist die Variable verfügbar, vorher nicht. Die Freigabe mittels fpc_finalize. Ohne fpc_finalize-Aufruf wird trotz interface auch nichts freigeben.

Code: Alles auswählen

 
var x: trec;
 
Ruft fpc_initialize beim Prozedurbeginn und fpc_finalize am Ende auf

Code: Alles auswählen

 
new(rec);
dispose(rec);
 
New ruft automatisch fpc_initialize auf (obwohl das der Dokumentation widerspricht) und dispose fpc_finalize.

Code: Alles auswählen

 
getmem(rec);
freemem(rec);
 
Ruft nichts auf. Nicht verwenden!
theo hat geschrieben:
Eine Möglichkeit habe ich mir überlegt. Man könnte eine QWord Kontrollvariable mitführen und diese nach dem Createn auf einen bestimmten konstanten Wert setzen.
Vorher kann man diese Variable gegen die Konstante prüfen. Dass die Variable zufällig diesen einen, bestimmten Anfangswert bekommt, ist extrem unwahrscheinlich.
Unsinn. Der Wert kommt nicht zufällig, sondern ist der Wert, den der letzte Record dort hatte

Benutzeravatar
theo
Beiträge: 10874
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

BeniBela hat geschrieben: Unsinn. Der Wert kommt nicht zufällig, sondern ist der Wert, den der letzte Record dort hatte
Kann ich nicht bebachten.

Code: Alles auswählen

type
 
  TRec=Record
    wd:QWord;
  end;     
...
procedure TForm1.Button1Click(Sender: TObject);
var a:TRec;
begin
  Memo1.lines.Add(IntToStr(a.wd));
  a.wd:=1234;
  Memo1.lines.Add(IntToStr(a.wd));
end;     

BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von BeniBela »

Weil die LCL es durcheinander bringt. Probiere es in einem Konsolenprogramm

Benutzeravatar
theo
Beiträge: 10874
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Schon klar, dass das Flickwerk ist.
Das was ich wollte, geht so einfach nicht.
Ich kann es anders lösen, es wird aber umständlicher.

Danke an alle.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Socke »

theo hat geschrieben:
Socke hat geschrieben:Dann setz die Variable doch auf nil, sobald sie verfügbar ist!
Und wann wäre das innerhalb eines Records?
Unmittelbar, nachdem du den Speicher für den gesamten Record reservierst. Der Record erscheint ja nicht zufällig im Speicher.
Damit du das nicht an allen Stellen in deinem Code machen musst, an denen du diese Records erzeugst, kannst du dir auch eine Factory-Prozedur bauen (die dann selbstverständlich nicht zum Record gehört).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 10874
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Socke hat geschrieben:
theo hat geschrieben:
Socke hat geschrieben:Dann setz die Variable doch auf nil, sobald sie verfügbar ist!
Und wann wäre das innerhalb eines Records?
Unmittelbar, nachdem du den Speicher für den gesamten Record reservierst. Der Record erscheint ja nicht zufällig im Speicher.
Damit du das nicht an allen Stellen in deinem Code machen musst, an denen du diese Records erzeugst, kannst du dir auch eine Factory-Prozedur bauen (die dann selbstverständlich nicht zum Record gehört).
Wie meinst du das?
Ich möchte nicht, dass der User irgendwas spezielles machen muss mit dem Record, sonst würde ich das Create einer Klasse benutzen.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Socke »

theo hat geschrieben:Wie meinst du das?
Ich möchte nicht, dass der User irgendwas spezielles machen muss mit dem Record, sonst würde ich das Create einer Klasse benutzen.
Im Prizip gehört jeder Entwickler geteert und gefedert, der auf einen Record lesend zugreift, ohne ihn vorher zu initialisieren. Das kann er entweder selbst machen (für mich wäre das "nichts spezielles" sondern etwas selbstverständliches) oder du forderst (Dokumentation!), dass der Record ausschließlich über eine Factory-Prozedur erstellt wird (bei Ablage auf dem Heap) oder du entscheidest dich doch für ein Objekt.
BeniBela hat geschrieben:New ruft automatisch fpc_initialize auf (obwohl das der Dokumentation widerspricht) und dispose fpc_finalize.

Code: Alles auswählen

getmem(rec);
freemem(rec); 
Ruft nichts auf. Nicht verwenden!
New() und Dispose() rufen fpc_initialize bzw. fpc_finailize auf, wenn referenzgezählte Typen (COM-Interfaces, Unicode-/AnsiStrings, dynamische Arrays, NICHT für Objekte/Klassen, CORBA-Interfaces, statische Arrays und Shortstrings) im Record verwendet werden. Diese Typen benötigen zwingend eine Initialisierung. Dies fehlt in der Tat in der Dokumenation.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Mathias »

Im Prizip gehört jeder Entwickler geteert und gefedert, der auf einen Record lesend zugreift, ohne ihn vorher zu initialisieren.
Wird ein record nicht mit Nullen/LeerString aufgefüllt, oder war dies Zufall ?

Code: Alles auswählen

var
  r: record
    a, b, c: integer;
    s: string;
  end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  with r do begin
    WriteLn(a);
    WriteLn(b);
    WriteLn(c);
    WriteLn(s);
  end;
end;
Zuletzt geändert von Mathias am Do 21. Jan 2016, 18:31, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10874
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Mathias hat geschrieben:
Im Prizip gehört jeder Entwickler geteert und gefedert, der auf einen Record lesend zugreift, ohne ihn vorher zu initialisieren.
Wird ein record nicht mit Nullen/LeerString aufgefüllt,
Nein, was ich allerdings zumindest schade finde.
Wir wäre es mit einem neuen Type InitializedRecord ?

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Mathias »

So könnte man dies umgehen, ist zwar etwas mühsam.

Code: Alles auswählen

var
  r: record
    a, b, c: integer;
    s: string;
  end
  = (a: 0; b: 0; c: 0; s: '');   
Für Codetools wäre das eine gute Ergänzung, wen man nach dem "=" Ctrl+Shift+C drücken könnte.

Nein, was ich allerdings zumindest schade finde.
Müsste bei

Code: Alles auswählen

WriteLn(r.a);
keine Warnung kommen, wen die Variable nicht initialisiert ist ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10874
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Ja, Global ist das initialisiert, aber so verwende ich die eher nicht.

So ist beides nicht initialisiert. Inkl. Warnung.

Code: Alles auswählen

type
  tr= record
    a, b, c: integer;
    s: string;
  end ; 
 ....
procedure TForm1.Button1Click(Sender: TObject);
var r:tr;
  re: record
    a, b, c: integer;
    s: string;
  end;
begin
  writeln(r.a);
  writeln(re.a);
end;
 

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Mathias »

Stimmt, inerhalb einer Methode, hängt der Bezeichner in der Luft.

Dies ist aber bei einem einfachen Integer auch der Fall.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  i:Integer;
begin
  writeln(i);
end;
Zuletzt geändert von Mathias am Fr 22. Jan 2016, 18:57, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Socke »

Socke hat geschrieben:New() und Dispose() rufen fpc_initialize bzw. fpc_finailize auf, wenn referenzgezählte Typen (COM-Interfaces, Unicode-/AnsiStrings, dynamische Arrays, NICHT für Objekte/Klassen, CORBA-Interfaces, statische Arrays und Shortstrings) im Record verwendet werden. Diese Typen benötigen zwingend eine Initialisierung. Dies fehlt in der Tat in der Dokumenation.
Einschränkung: es werden nur die referenzgezählten Typen initialisiert; alle anderen Felder bleiben uninitialisiert.

@theo: geht es dir hier nur im COM-Interfaces oder allgemein um Record-Felder?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten