Es kompiliert nicht alles ( inline )

Für Fragen rund um die Ide und zum Debugger
Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Es kompiliert nicht alles

Beitrag von theo »

Mathias hat geschrieben:Habe ich es richtig gemacht ?


Ist eigentlich jetzt egal, der Bugreport wurde als Duplikat eingestuft.
Der Hauptreport dazu ist hier: http://bugs.freepascal.org/view.php?id=18121

Aber mal eine andere Frage: Wie kommt man eigentlich auf so eine Idee, eine einfache Methode zu "inlinen"?

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Aber mal eine andere Frage: Wie kommt man eigentlich auf so eine Idee, eine einfache Methode zu "inlinen"?

Eben, weil es eine einfache Methode ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Es kompiliert nicht alles

Beitrag von theo »

Mathias hat geschrieben:
Aber mal eine andere Frage: Wie kommt man eigentlich auf so eine Idee, eine einfache Methode zu "inlinen"?

Eben, weil es eine einfache Methode ist.


Und was versprichst du dir davon? Soll das schneller zeichnen? :lol:
Bisher kannte ich das nur von normalen, kurzen Funtkionen die man evtl. in engen Loops benützt.

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Und was versprichst du dir davon? Soll das schneller zeichnen? :lol:

Vieleicht eine MikroSekunde. ;)
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Der Thread ist Uralt, aber ich musste leider feststellen, das dieser Bug mit dem Inline wieder das ist. (FPC 3.0.4, Lazarus 1.8.4)

Ich habe vorhin mit folgender procedure geübt, sie ist Bestandteil eines TypenHelper und gehört zu einer Packe von mir.

Code: Alles auswählen

procedure Tmat4x4Helper.Translate(x, y, z: GLfloat); inline;
var
  i: integer;
begin
//  for i := 0 to 2 do begin
//    Self[3, i] += Self[0, i] * x + Self[1, i] * y + Self[2, i] * z;
//  end;
  Self[3, 0] += x;
  Self[3, 1] += y;
  Self[3, 2] += z;
end;

Ich werde später mal versuchen den Fehler auf ein Mini-Beispiel einzugrenzen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

So habe es nun auf ein Minimum reduziert. Ich kann ich der Unit2 Result ändern, wie ich will, es wird nicht angenommen.
Sobald ich aber in der Unit1 etwas ändere, auch wen es nur eine Leerzeilen einfügen ist, dann wird der neue Wert von Result übernommen.

Kann das sonst noch wer nachvollziehen ?

Getestet mit FPC 3.0.4, Lazarus 1.8.4, Linux 64Bit.

Ich habe es gerade noch mit der Trunk probiert.
Dabei habe ich auch Win32 und Win64 probiert.
Der Bug ist überall.

Wie oben beschrieben auch mit Type Helper:

Code: Alles auswählen

// Unit1
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  i.geti;
  Caption := IntToStr(i);
end;
 
// Unit2
type
  TIntegerHelper = type Helper for Integer
    procedure geti;
  end;
 
implementation
 
procedure TIntegerHelper.geti; inline;
begin
  Self := 7;
end;


Einzig was geht, ist eine nackte Funktion:

Code: Alles auswählen

function getii: Integer; inline;
begin
  Result := 8;
end;
Dateianhänge
inline_bug.tar.gz
(64.4 KiB) 114-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Es kompiliert nicht alles

Beitrag von Michl »

Ich habe es jetzt noch nicht getestet, aber war der Bug jemals gefixt? Lt. Bugeintrag eigentlich ja nicht. https://bugs.freepascal.org/view.php?id=25797

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Ich habe es jetzt noch nicht getestet, aber war der Bug jemals gefixt? Lt. Bugeintrag eigentlich ja nicht. https://bugs.freepascal.org/view.php?id=25797

Dieser Report bezieht sich auch nackte Funktionen, diese gehen, wie ich oben beschrieben habe.
Was noch nicht geht, ist wen inline in Classen oder Type Helper gepackt ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: Es kompiliert nicht alles

Beitrag von Erwin »

Über ähnlichen Fehler bin ich auch schon gestolpert. Weiß aber nicht, in wie weit es mit diesem hier zusammen hängt.
Aber bei mir tritt der Fehler dann bei folgender Konstellation auf:

Habe ein Unit für Records. Dort erstelle ich einen TMalRecord mit zum Beispiel Angaben von 'Hoehe' und 'Breite'.

Im Hauptunit (also vom Formular) wird der Record dann ... zugewiesen (sagt man das so)? 'BildMalRecord:=TMalRecord'. Des weiteren wird auch in dieser Hauptunit die Daten übertragen/eingetragen (zb. BildMalRecord.Hoehe:=50, BildMalRecord.Breite:=200). Und dann eine Funktion FMalen aufgerufen ('FMalen()')

In einem Dritten Unit ist dann die Funktion 'FMalen()'. Innerhalb dieser Funktion wird dann eben 'BildMalRecord.Hoehe' etc. benutzt, also ausgelesen und dann gemalen.

Wenn ich aber hergehe, und im Unit für Records und im Hauptunit den Namen von 'Hoehe' und 'Breite' in anderen Namen ändere, führt er das Programm ohne Fehlermeldung aus.
Wenn ich dann in 2 Schritten, also
'Hoehe' in HoeheVar' und 'Breite' in 'BreiteVar' ändere, kompiliere dann
'HoeheVar' in 'Breite' und zuletzt 'BreiteVar' in 'Hoehe' umändere, und kompiliere,
zeichnet es dann mit den Daten von Hoehe die Breite und umgekehrt.

Dies 'klappt' so lange, bis man im Dritten Unit etwas ändert oder schreibt. Für mich spricht vieles dafür, dass es eben die Dritte Unit (wo die Funktion FMalen ist) so lange ignoriert, also weder neu Kompiliert und auch nicht die Vars überprüft, bis sich was ändert.

Mit direkten Variablen hingegen geht das nicht. Aber diese werden ja auch nicht extra noch mal zugewiesen wie ein Record.

Und ja, ich kann es mir teils denken: Gehört sich so, weil man sich Zeit sparen will etc. usw.

Allerdings bei Delphi hingegen geht dies nicht. Der meckert grundsätzlich, und nicht erst, wenn sich auch in der Dritten Unit sich was ändert.
Und ja, ich hätte mir den Satz eins weiter oben sparen können. Weil vermute mal, das 'natürlich' es dann Delphi falsch macht, während Lazarus es richtig macht. Und ansonsten ja generell der Fehler am Nutzer, also mir liegt.
Lazarus 2.2.0 / FP 3.2.4

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: Es kompiliert nicht alles

Beitrag von Erwin »

Mein Fall betreffend, habe ich inzwischen heraus gefunden, dass wenn man in der Dritten Unit, wo die Funktion für malen ist, wenn man dort die Unit des Record in die Uses einfügt, es dann die Veränderungen in den anderen Units generell mitbekommt.
Weil ursprünglich war es ja nicht nötig, die Unit Record in die uses von Unit Malen aufzulisten.
Tja, das macht es für mich etwas unnötig aufgebläht.

Vielleicht ist der Bug vom Threadersteller auf ähnliche Weise leicht zu beheben?
Oder wurde da nicht schon bereits ähnliches vermutet, also dass ein Zuweisung im geschützten (lokalen) statt offen (globalen) Bereicht ist? Was ja vielleicht teils auf das gleiche hinaus läuft: Das eben Änderungen dadurch ignoriert werden?
Lazarus 2.2.0 / FP 3.2.4

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Vielleicht ist der Bug vom Threadersteller auf ähnliche Weise leicht zu beheben?

Mein Bug kann ich nur beheben, wen ich während der Entwicklung auf inline verzichte.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Ich habe es mal im Typen Helper Kopf probiert. Nützt leider nichts, das Problem besteht weiterhin.

Code: Alles auswählen

type
  TIntegerHelper = type Helper for Integer
    procedure geti; inline// Versuch
  end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Es kompiliert nicht alles

Beitrag von kupferstecher »

Mathias, besteht bei dir nur noch das Problem, dass eine Änderung in Inlinefunktionen in anderen Units nicht übernommen wird, oder kompiliert es gar nicht mit inline-Schlüsselwort?

Wenn ersteres der Fall ist: Das Problem ist ja, dass der FPC fürs schnelle Compilieren nur die Dateien neu übersetzt, die sich auch geändert haben. Beim Inlinen wird der Code aber in den Code der anderen Unit eingebettet, die andere Unit müsste also ebenfalls neu übersetzt werden, obwohl sich der Quellcode selbst nicht geändert hat, nur die geinlineten Funktionen. Das zu wissen hilft vielleicht insofern weiter, dass man besser versteht wann das Problem genau auftritt und sich danach richten kann.

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

Re: Es kompiliert nicht alles

Beitrag von Mathias »

Also es ist so, wen ich den Result-Wert in der Unit2 ändere, wird die Änderung ignoriert.
Aber sobald ich was in der Unit1 ändere, Leerzeile einfügen genügt, bei Leerzeichen passiert nichts.

Ohh, jetzt habe ich gerade festgestellt, das die Funktion Test nackt ist, also keine Klasse oder Typenhelper.

Somit ist der Bug auch in nackten Funktionen nicht behoben. Und dies in der stable und Trunk.
Wen man weiter oben liest, war dieser Bug bei den nackten Funktionen mal behoben gewesen und ist jetzt wieder vorhanden.

PS: Ich habe dies im Wiki vermerkt: http://wiki.freepascal.org/Inline/de
Wen der Bug behoben ist, werde ich die Änderung wieder entfernen/ergänzen.
Dateianhänge
inline_bug.tar.gz
(125.81 KiB) 109-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten