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

Es kompiliert nicht alles ( inline )

Beitrag von Mathias »

Ich habe folgende Zeilen in einer Unit, diese sollen beim Zeichen von Körpern verhindern, das es nicht weniger als 5 Sektoren gibt.

Code: Alles auswählen

 
  public
    property Sektoren: integer read FSektoren write SektorenWrite;
.......
procedure TKoerper.SektorenWrite(Sektoren: integer); inline;
begin
  FSektoren := Sektoren;
  if FSektoren < 5 then begin
    FSektoren := 5;
  end;
end;

Vorhin hatte ich anstelle der 5 eine 3, aber wen ich mit F9 starte, hat es immer noch 3 Sektoren.

Interessanterweise, wen ich ein paar Zeilen weiter unten was ändere, z.B. bei Ring, dann nimmt der Compiler diese Werte an.
Aber die oberen Zeilen bei SektorenWrite werden immer noch ignoriert.

Mache ich aber "Aufräumen und Kompilieren...", dann werden die Werte von SektorenWrite übernommen.

Ist dies ein Fehler des Kompilers und mache ich was falsch ?

Code: Alles auswählen

procedure TCylinder.WriteVertex;
var
  vPos: integer;
 
begin
  SetLength(vertex, FSektoren * 18);
  SetLength(normale, FSektoren * 18);
  KreisTabelleBerechnen;
 
  vPos := 0;
  Ring(1, 1, -1, 1, vPos);
  vPos := FSektoren * 6;
  Ring(1, 0, 1, 1, vPos);
  vPos := vPos + FSektoren * 6;
  Ring(0, 1, -1, -1, vPos);
 
  inherited WriteVertex;
end;   
Zuletzt geändert von Mathias am Sa 11. Nov 2023, 16:21, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Es kompiliert nicht alles

Beitrag von m.fuchs »

Mathias hat geschrieben:[...]diese sollen beim Zeichen von Körpern verhindern, das es nicht weniger als 5 Sektoren gibt.

Falsch, sie verhindern dass es weniger als 5 Sektoren gibt!

Deine Bezeichner sind etwas unglücklich gewählt. TKoerper.SektorenWrite hat einen Parameter namens Sektoren, der also genauso wie die Property heißt. Das fordert eine Verwirrung geradezu heraus. Nenn den Parameter doch lieber ASektoren oder noch besser du hältst dich an die Vorschläge SetSektoren für die Prozedur und AValue für den Parameter.

Sowas musst du übrigens nicht von Hand tippen. Gibt beispielsweise mal folgendes ein.

Code: Alles auswählen

type
  TTest = class(TObject)
    public
      property Sektoren: Integer;
  end;


Platziere den Cursor nun auf Sektoren und drücke Strg+Shift+C. Du erhältst das hier:

Code: Alles auswählen

 TTest = class(TObject)
    private
      FSektoren: Integer;
      procedure SetSektoren(AValue: Integer);
    public
      property Sektoren: Integer read FSektoren write SetSektoren;
  end;
 
(* ... *)
 
implementation
 
procedure TTest.SetSektoren(AValue: Integer);
begin
  if FSektoren = AValue then Exit;
  FSektoren := AValue;
end;

Dann kannst du die Setter-Methode anpassen an deine Wünsche.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

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 »

Danke, jetzt geht es.

Bringt diese Abfrage einen grossen Vorteil "if FSektoren = AValue..." ?
Braucht dies nicht fast soviel Zeit wie die Zuweisung.

Code: Alles auswählen

procedure TKoerper.SetSektoren(AValue: integer);
begin
  if FSektoren = AValue then begin
    Exit;
  end;
  if AValue < 5 then begin
    AValue := 5;
  end;
  FSektoren := AValue;
end;


Was ich noch festgestellt habe, wen man eine Deklaration ohne "write"macht, dann ist die Variable nach aussen schreibgeschützt.:

Code: Alles auswählen

property Sektoren: integer read FSektoren;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Es kompiliert nicht alles

Beitrag von m.fuchs »

Du kannst die Prüfung natürlich auch weglassen, wenn sie dir unnötig erscheint.

Übrigens kannst du auch eine writeonly Property erstellen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

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 »

Das Problem mit dem nicht kompilieren ist wieder da.
Ich hatte vorhin versehentlich for i := 0 to 3 do anstelle for i := 0 to 2 do geschrieben.
Das gibt natürlich eine Schutzverletzung.
Ich habe den Wert auf 2 korigiert und es kam immer noch eine SV.
Erst als ich wieder "Aufräumen und Kompilieren..." macht, dann funktionierte der Code wider.
Dann habe ich 234 geschrieben, F9 gedrückt, das Programm lief immer noch.
Mit so einem grossen Wert dürfte ja gar nichts mehr gehen. :roll:

Code: Alles auswählen

type
  TVector3f = array[0..2] of GLfloat;
 
function TVertexModif.Negate(Vector: TVector3f): TVector3f; inline;
var
  i: integer;
begin
  for i := 0 to 2 do begin
    Result[i] := Vector[i] * (-1);
  end;
end;     
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Es kompiliert nicht alles

Beitrag von wp_xyz »

Ich denke, dass du dir die Compiler-Einstellungen verkonfiguriert hast. Ich würde die Radikalkur machen:
  • Den Lazarus-Profil-Ordner umbenennen (üblicherweise %appdata%\Local\Lazarus, es sei denn du verwendest den Kommandozeilenparameter --pcp oder --primary-config-path oder die Konfigurationsdatei lazarus.cfg, mit denen ein anderer Ordner eingestellt werden kann)
  • Lazarus neu starten, damit werden neue Defaultparameter genommen
  • Leider musst du dir die Benutzeroberfläche neu konfigurieren und alle benötigten Komponenten neu installieren. Aber vielleicht geht der erste Test deines Programms ja auch ohne
  • Falls das nichts bringt, kannst du den alten Profil-Ordner jederzeit wieder zurück-umbenennen, um die alten Einstellungen wieder zu bekommen

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 »

Hat leider nichts gebracht.

Schreibe ich sowas, dann merkt er, das ein Syntax-Fehler vorhanden ist.

Code: Alles auswählen

  i:=strtoint(i);
  for i := 0 to 1232 do begin
    Result[i] := Vector[i] * (-1);
  end;
 

Entferne ich die Zeile i:=strtoint(i); läuft das Programm wieder ohne Fehler, obwohl 1232 viel zu hoch 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 »

Sry, falsch gelesen.
Zuletzt geändert von theo am Mi 26. Feb 2014, 22:47, insgesamt 1-mal geändert.

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

Re: Es kompiliert nicht alles

Beitrag von Michl »

k.A. woran das genau bei Dir liegt. Ich würde versuchen, das Ganze mal auf ein Minimalbsp zu begrenzen (siehe unten) und testen, ob dies tatsächlich problemlos durchläuft. Falls ja, würde ich Lazarus inkl. Registereinträge etc. entfernen und neu installieren - ist ja nun nicht so ein Riesenakt.

Minimalbsp (ich habe es nicht hinbekommen, dass der von Dir gepostete Code funktioniert)

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, GL;
 
type
 
  TVector3f = array[0..2] of GLfloat;
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function Negate(Vector: TVector3f): TVector3f;
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Vec: TVector3f;
begin
  Vec[0]:=0;
  Vec[1]:=1;
  Vec[2]:=2;
  Vec:=Negate(Vec);
end;
 
function TForm1.Negate(Vector: TVector3f): TVector3f; inline;
var
  i: integer;
begin
  for i := 0 to 2{34} do begin  //diese Zeile auf 3 ändern sollte ein SIGSEGV liefern!
    Result[i] := Vector[i] * (-1);
  end;
end;
 
end

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 noch was raus gefunden, wen ich in meinem Code das inline entferne, dann compiliert er richtig.
Wen ich meinen ersten Post mit den Sektoren angucke, war da auch ein inline.

Interessanterweise passiert der Fehler bei deinem Miniprogramm nicht, obwohl dort auch inline steht.

würde ich Lazarus inkl. Registereinträge etc. entfernen und neu installieren

Auf meinem zweit PC, tritt genau der gleiche Fehler auch auf.
Als nächstes installiere ich mal Lazarus in der VirtualBox mit WinXP.

Nachtrag:Wen ich in der VirtualBox kompiliere, tritt genau das gleiche Problem auf.

Könnte dies ein Bug von FreePascal sein ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Es kompiliert nicht alles

Beitrag von wp_xyz »

Könnte dies ein Bug von FreePascal sein ?

Keine Ahnung. Ohne Code, der von jedem nachvollzogen werden kann und den Fehler zeigt, kann das niemand sagen, und auch die Entwickler von FreePascal werden nicht viel mit einem lückenhaften BugReport machen können.

Welchen Lazarus und welchen FPC verwendest du? Es gibt immer wieder Leute, die haben noch 0.90er-Versionen.

Das Beispiel von Michl läuft bei mir einwandfrei, egal mit oder ohne inline.
Ach ja noch: Muss "inline" nicht im interface-Teil deklariert werden?

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

Re: Es kompiliert nicht alles

Beitrag von Michl »

wp_xyz hat geschrieben:Muss "inline" nicht im interface-Teil deklariert werden?
Ja, mein C+P Fehler vom probieren...

Mathias hat geschrieben:Könnte dies ein Bug von FreePascal sein ?
Glaub ich nicht, wenn das gepostete Projekt bei einem ungültigen Wert einen SIGSEGV meldet, warum sollte das Deinem Projekt anders sein? Glaube der Hund ist woanders begraben. Könntest ja Dein Projekt (möglichst minimiert per Zip) hier posten...

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 eine Miniprogramm geschrieben, da ist der Fehler auch nachvollziehbar.
Ich kann in vec3 x und y vertauschen, nach einem Neustart (F9) hat dies keine Wirkung.
Ich habe auch bei Kompilieren und Linken verschiedene Einstellungen ausprobiert, alles ohne Erfolg.
Entferne ich inline;, dann arbeitet der Compiler korrekt.

Nehme ich die Funktion vec3 in die Hauptunit (Unit1), dann arbeitet der Compiler auch fehlerfrei.

Ich hoffe ihr könnt das nachvollziehen.

Unit1:

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  SysUtils, Forms, StdCtrls, Unit2;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var
  v: TVector3f;
begin
  v := vec3(1, 2, 3);
  Memo1.Lines.Add(FloatToStr(v[0]));
  Memo1.Lines.Add(FloatToStr(v[1]));
  Memo1.Lines.Add(FloatToStr(v[2]));
  Memo1.Lines.Add('---');
end;
 
end.
 

Unit2:

Code: Alles auswählen

unit Unit2;
 
{$mode objfpc}{$H+}
 
interface
 
type
  TVector3f = array[0..2] of single;
 
function vec3(x, y, z: single): TVector3f;
 
implementation
 
function vec3(x, y, z: single): TVector3f; inline;
begin
  Result[0] := y;  // Hier vertausche ich x und y.
  Result[1] := x;
  Result[2] := z;
end;
 
end.
 
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 »

Verstehe ich nicht. Ich habe Dein Bsp probiert. Bei mir wird im Memo
2
1
3
angezeigt, tausche ich x und y wird
1
2
3
angezeigt mit und ohne inline - und das ist auch korrekt so. Und bei Dir ist das anders?

Code: Alles auswählen

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

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

Re: Es kompiliert nicht alles

Beitrag von Michl »

Ich muss mich korrigieren. Nachdem ich das Projekt in ein separates Verzeichnis gespeichert und von dort aus gestartet habe, kann das Fehlverhalten so bestätigen. Scheinbar wird Unit2 trotz Änderung nicht neu kompiliert. Mit Shift-F9 wird der Fehler dann korrigiert (Unit2 neu kompiliert)! Komischerweise, wie Du schon schriebst, nur mit inline!

Win7, Lazarus 1.0.14 und Lazarus 1.3-Trunc FPC-Trunc, gleiches Verhalten!

Falls es noch jemand testen will, habe ichs mal angehangen...

Könnt ein Fehler der IDE sein, dass nicht erkannt wird, dass sich der Code geändert hat und somit nicht erneut kompiliert wird?!

Code: Alles auswählen

function vec3(x, y, z: single): TVector3f; inline;
begin
  Result[0] := x*10// Hier vertausche ich x und y.
  Result[1] := y*10;
  Result[2] := z*10;
end;

ergibt eine Memo-Ausgabe:
1
2
3
Dateianhänge
Test kompilieren.zip
(125.94 KiB) 164-mal heruntergeladen
Zuletzt geändert von Michl am Do 27. Feb 2014, 22:39, insgesamt 1-mal geändert.

Code: Alles auswählen

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

Antworten