[Erledigt] Boolean-Prüfung funktioniert nicht

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

[Erledigt] Boolean-Prüfung funktioniert nicht

Beitrag von MacWomble »

Ich habe in meinem Programm

Code: Alles auswählen

 
        if DoSave = True then
        begin
          if qryPosition.State = dsEdit then
         ...
 


DoSave ist definitiv FALSE, trotzdem wird der Zweig ab 'begin' abgearbeitet.
Das selbe Verhalten habe ich, wenn ich (das empfohlene)

If DoSave Then

verwende.

DoSave ist als Boolean definiert und der Debugger zeigt mir auch false an.
Zuletzt geändert von MacWomble am Fr 27. Apr 2018, 21:12, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

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

Re: Boolean-Prüfung funktioniert nicht

Beitrag von theo »

Woran erkennst du das?

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Boolean-Prüfung funktioniert nicht

Beitrag von MacWomble »

Siehe Screenshot
Bildschirmfoto vom 2018-04-27 11-24-59.png
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

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

Re: Boolean-Prüfung funktioniert nicht

Beitrag von theo »

Ich meine, dass er den Codeblock durchläuft?
Es kann ja eigentlich nicht sein, sonst würde nichts laufen.
"Spinnt" der Debugger?

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Boolean-Prüfung funktioniert nicht

Beitrag von MacWomble »

Ich bin im Einzelschrittmodus durch die Routine. Sieht man im Screenshoot auch, dass er in diesem Codebereich ist.
Es werden definitiv die Befehle im 'True'-Block ausgeführt!
Zuletzt geändert von MacWomble am Fr 27. Apr 2018, 12:33, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Boolean-Prüfung funktioniert nicht

Beitrag von siro »

Hallo MacWomble,

oft bauen die Compiler eine gemeinsamen Codeabschnitt für die If Then Abfragen,
da lässt man sich schnell ins Boxhorn jagen, er kommt da zwar rein, führt aber nix wirklich aus
bzw. nur Code der für beide Abschnitte gültig ist.
Das passiert besonders gern wenn man die Optimierungen eingeschaltet hat.
Im Zweifel schaue ich mir dann immer den Assemblercode an.
Prüf das mal mit einer zusätzlichen Variable, indem Du die vor der Abfrage auf FALSE setzt
und in der IF TRUE Abfrage dann auf TRUE setzt.
Nach der IF then schaust Du wie die Variable dann steht.

Code: Alles auswählen

 
var f:Boolean;
 
f:=FALSE;
if DoSave = TRUE then
begin
   f := TRUE;
.....


hier guckst Du Dir dann das f dann an.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Boolean-Prüfung funktioniert nicht

Beitrag von MacWomble »

@siro

F ist true, also arbeitet er es ab!

Aber das wusste ich ja bereits. Siehe oben.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Benutzeravatar
gladio
Beiträge: 217
Registriert: Sa 21. Jun 2014, 06:15
OS, Lazarus, FPC: Win10-64 - aktuelle Lazarus/FPC Standard-Edition
CPU-Target: 64Bit
Wohnort: Rügen

Re: Boolean-Prüfung funktioniert nicht

Beitrag von gladio »

und wenn du das mal andersherum angehst:

Code: Alles auswählen

if DoSave <> false then
begin

oder

Code: Alles auswählen

if DoSave = false then 
  //mach irgendwas oder nichts
  //einfach mal beep
else
begin
  if qryPosition.State = dsEdit then
..
 
Zuletzt geändert von gladio am Fr 27. Apr 2018, 12:41, insgesamt 1-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Boolean-Prüfung funktioniert nicht

Beitrag von af0815 »

Ist das DoSave eindeutig ?

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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: Boolean-Prüfung funktioniert nicht

Beitrag von m.fuchs »

Das = True würde ich weglassen, aber das dürfte nicht das Problem sein.

Lösche mal alle kompilierten Dateien (excutable und ppu) und bau das ganze Projekt neu. Das klingt für mich eher, als ob sich der Debugger irgendwo verschluckt und noch mit alten Kompilaten arbeitet.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Boolean-Prüfung funktioniert nicht

Beitrag von siro »

Ist das DoSave eine Funktion ?
Dann könnte das Ergebnis evtl. undefiniert sein ? obwohl er ja FALSE anzeigt, laut deiner Beschreibung.

function DoSave:Boolean;
begin
// result vergessen...
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if DoSave then beep; // Zufalls bedingt
end;

ich würd jetzt zum Testen eine Variable definieren
var DoSave2:Boolean;

und diese dann abfragen.
solllte das richtig gehen, hängt es wohl mit der Funktion bzw. der Rückgabe zusammen.
Speicher / Stackproblem
-------------------------------
Neue Idee:

Kann das durch eine Vermischung der Boolean passieren ?

ein Boolean ist ja nur ein Byte
ein LongBool sind 4 Bytes
Wenn sich im Speicher der Wert z.B. auf 256 befindet, dann ist der Boolean False
während der LongBool vermutlich TRUE ist.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Boolean-Prüfung funktioniert nicht

Beitrag von MacWomble »

1. DoSave ist eine Variable
2. If DoSave Then hatte ich, geht aber auch nicht
3. Auch nach einem frischen (kompletten) kompilieren geht es nicht
4. Passiert dies an mindestens 10 Stellen im Programm


Es ist ein Form mit zwei Buttons Verwerfen und Speichern.

Im OnClick wird DoSave auf False bzw. auf True gesetzt.

Wenn DoSave wahr ist, wird der Datensatz gespeichert, im anderen Fall soll er nicht gespeichert werden.

(Code gekürzt)

Code: Alles auswählen

 
unit frm_position;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, Controls, ctrfunctions, DB, DBCtrls, DBGrids, Dialogs, ExtCtrls, FileUtil, Forms, frm_mengeneinheiten,
  frm_textbausteine, Graphics,
  LCLType, StdCtrls, DBExtCtrls, SysUtils;
 
type
 
  { TfrmPosition }
 
  TfrmPosition = class(TForm)
    lblArtikelnummer: TLabel;
   ...
    procedure btnBausteinPositionClick(Sender: TObject);
    procedure dbeLohnExit(Sender: TObject);
    procedure dblPositionsArtChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure btnSpeichernClick(Sender: TObject);
    procedure btnVerwerfenClick(Sender: TObject);
  private
 
  public
 
  end;               
 
var
  frmPosition: TfrmPosition;
  DoSave: boolean;
 
function BearbeiteAuftragsPosition(IDAuftrag: integer; IDPosition: integer; Neu: boolean): boolean;
 
 
implementation
 
uses
  dtm_artikel, dtm_auftrag, dtm_basis, frm_getartikel;
 
{$R *.frm} 
 
function BearbeiteAuftragsPosition(IDAuftrag: integer; IDPosition: integer; Neu: boolean): boolean;
var
  Suchtext: string;
  LastRec: integer;
  PosNeu: integer;
  IDArtikel, IDPreis: integer;
  StSatz, FStSatz: string;
  F: TfrmPosition;
  LDat: boolean;
  begin
  with dtmAuftrag do
  begin
    qryPosition.Connection.StartTransaction;
      if IDPosition = 0 then
      if MessageDlg('Es sind noch keine Positionen vorhanden. Wollen Sie jetzt eine anlegen?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
        Neu := True
      else
      begin
        Result := False;
        exit;
      end;
    LDat := False;
    case dtmAuftrag.qryAuftragsListe.FieldByName('auf_typ').AsInteger of
      10, 40, 50, 53, 59: LDat := True;
    end;
    if Neu then
      CreateNewPosition(IDPosition);
 
    if IDPosition > 0 then
    begin
      OpenSQLSet(qryPosition, 'Select * from AuftragsPositionen where idauftragsposition = ' + IntToStr(IDPosition));
      BerechnePosition;
 
      F := TfrmPosition.Create(nil);
 
      try
        F.ShowModal;
 
// Hier findet der Spuk statt:
 
        if DoSave = True then
        begin
          if qryPosition.State = dsEdit then
            qryPosition.ApplyUpdates;
          qryPosition.Connection.Commit;
          if qryPosition.FieldByName('fk_posart').AsInteger=2 then
             ExecSQLDirect(dtmBasis.qrySQL,'Update AuftragsPositionen set apo_artikelgruppe=0 '+
             'where idauftragsposition=' + qryPosition.FieldByName('idauftragsposition').AsString);
 
          qryPositionsListe.Refresh;
          qryPositionsListe.Locate('idauftragsposition', qryPosition.FieldByName('idauftragsposition').AsInteger, []);
          Result := True;
        end
        else
        begin
// Hier kommt das Programm nie hin
          qryPosition.Connection.Rollback;
          Result := False;
        end;
      finally
        FreeAndNil(F);
      end;
    end;
  end;
end;           
 
 
 
 
{ TfrmPosition }
 
procedure TfrmPosition.btnSpeichernClick(Sender: TObject);
begin
  DoSave := True;
  Close;
end;
 
procedure TfrmPosition.btnVerwerfenClick(Sender: TObject);
begin
  if MessageDlg('Sollen wirklich alle Änderungen verworfen werden?', mtWarning, [mbYes, mbNo], 0) = mrYes then
  begin
    DoSave := False;
    Close;
  end;
end
 
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Boolean-Prüfung funktioniert nicht

Beitrag von af0815 »

Irgendwie schon komisch !

a) DoSave in den implementationsteil, oder MUSS es zwingend im Interface stehen. Damit es zumindest nur unitglobal ist.
b) DoSave zwingend vor der Verwendung initialisieren
c) Abfrage immer mit Klammer versehen
IF (DoSave = true) THEN

Wenn du Fenster Modal öffnest, so würde ich das ModalResult nehmen für die Entscheidung. Ich vermeide soweit es geht globale Variablen. Unitglobal, ja wenn es wirklich Sinn macht.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Boolean-Prüfung funktioniert nicht

Beitrag von MacWomble »

ModalResult ?

Kenne ich nicht, muss ich mir ansehen.
Das kann hier aber auch nicht helfen.

DoSave muss innerhalb dieser einen Unit erreichbar sein.

Muss aber jetzt erst mal zu einem Kunden...

Zwischenergebnis:;

1. In den Implementation-Teil verschoben, hilft nichts
2. Aus If DoSave=True then wieder If DoSave Then gemacht, hilft nichts

Das ganze ist total unlogisch und im Moment zweifle ich wirklich an Lazarus. So etwas darf nicht passieren!
Wenn ein Initialisierungsfehler vorliegt, muss der Compiler darauf hinweisen. Einfach einen Boolean, welcher definitiv auf False steht als True zu interpretieren hat fatale Folgen! - Oder sollte ich mich täuschen.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

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

Re: Boolean-Prüfung funktioniert nicht

Beitrag von wp_xyz »

Ähnliches Verhalten hatte ich auch schon. Bist du sicher, dass alle Quellcodes aktuell comiliert sind (alle ppu's manuell löschen)? Gibt es eine zweite Version deines Quelltexts, die unbeabsichtigt aufgeruften wird?

Antworten