[Delphi] Bug in for loop?

Pagina: 1
Acties:
  • 152 views sinds 30-01-2008
  • Reageer

  • remier
  • Registratie: Maart 2000
  • Laatst online: 06-04-2023

remier

Tired of spam?

Topicstarter
Momenteel ben ik bezig met iets te proggen in D7, alleen kom ik iets heel raars tegen in een for lus :?

Kijk en huiver:

Afbeeldingslocatie: http://remier.dualcrew.net/stuff/for_loop_bug.gif
Het vakje rechtonder zijn de watches op het moment van de blauwe balk

Met bijbehorend stukje code:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    if (tblSupportDesk.State = dsEdit) then
    begin
      for i:= 0 to (tblSupportDesk.Fields.count-1) do
      begin
        try
          if (tblSupportDesk.Fields[i].fieldname <> 'Sleutel') then
          begin
            if(tblVergelijkSD.FieldByName(tblSupportDesk.Fields[i].fieldname).asString <> tblSupportDesk.FieldByName(tblSupportDesk.Fields[i].fieldname).asString) then
            begin
              // als er iets anders in vergelijkSG staat dan in tblsupportdesk
              // regel toevoegen aan s
              ChangeNote.add(tblSupportDesk.Fields[i].fieldname+' > "'+tblVergelijkSD.FieldByName(tblSupportDesk.Fields[i].fieldname).asString+'" = "'+tblSupportDesk.FieldByName(tblSupportDesk.Fields[i].fieldname).asString+'"');
            end;
          end;
          except
          end;
      end;


Zoals je zit heb ik een plaatje gemaakt met 3 watches: integer i, tblSupportDesk.Fields.count en tblSupportDesk.Fields.count-1, waarbij tblSupportDesk.Fields.count-1 ALTIJD 15 is, zelfs in de for-lus tijdens debuggen.

Wat er in de bovenstaande code gebeurd is dat de i in de for-lus tijdens telkens met 1 wordt opgehoogt TOT 15 (tblSupportDesk.Fields.count-1 is immers ten alle tijden 15) alleen na de 15 hoogt hij i nog een keer met 1 op waardoor i 16 wordt :S gevolg is dus dat ik een index out of bounds krijg tijdens het benaderen van het FIelds array van de TADOTable (tblSupportDesk.Fields[i].fieldname)..

Wat ik al geprobeerd heb is boven de for-lus een aparte interger de waarde van tblSupportDesk.Fields.count-1 toe te kennen en daarna pas de for-lus in te gaan, hier wordt i ook nog steeds 16.
Zeg ik for i:=0 to 15 do dan werkt het wel....


Wie weet wat ik over het hoofd zie of wat er fout gaat?

[ Voor 17% gewijzigd door remier op 15-12-2004 16:54 . Reden: Syntax codeblok ]

Heah what?!?? O, signature??


Verwijderd

Het try except blok is nogal smerig. Voor de rest is je code niet echt leesbaar, je frot teveel zaken tussen je haakjes. Als laatste klopt de identatie niet.

Wat is de TblVergelijkSD.Fields.Count?

[knip iets wat niet waar is]

Kijk:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  if (tblSupportDesk.State = dsEdit) then
    begin
      for i:= 0 to (tblSupportDesk.Fields.count-1) do
        try
          cFieldName:=tblSupportDesk.Fields[i].fieldname;
          cField:=tblSupportDesk.Fields[i].AsString;
          cVergField:=tblVergelijkSD.FieldByName(cFieldName).AsString;
          if (cFieldName <> 'Sleutel') then
            begin
              if(cField <> cVergField then
                begin
                  // als er iets anders in vergelijkSG staat dan in tblsupportdesk
                  // regel toevoegen aan s
                  ChangeNote.add(cFieldName+' > "'+cVergField+'" = "'+cField+'"');
                end;
            end;
        except
        end;
    end;


Is al een stuk leesbaarder..

[ Voor 104% gewijzigd door Verwijderd op 15-12-2004 16:52 ]


  • remier
  • Registratie: Maart 2000
  • Laatst online: 06-04-2023

remier

Tired of spam?

Topicstarter
De tblVergelijkSD.fields.count-1 moest zijn tblSupportDesk.Fields.count-1, had de screenshot nog net iets te vroeg gemaakt, maar het heeft geen invloed op mijn probleem.

Helaas is tblVergelijkSD.Fields[i].AsString; niet hetzelfde als tblVergelijkSD.FieldByName(tblSupportDesk.Fields[i].fieldname).asString;

Ik heb namelijk 2 ADO tabellen:

- tblSupportDesk;
- tblVergelijkSD;

Het probleem is dat de fields niet gelijk aan elkaar zijn, bv.:

- op tblSupportDesk.Fields[5].fieldname staat 'Omschrijving' en op tblVergelijkSD.Fields[5].fieldname 'Eigenaar'

- op tblSupportDesk.Fields[10].fieldname staat 'Behandeld_op' en op tblVergelijkSD.Fields[10].fieldname 'Antwoord_memo'

Omdat ik een vergelijking wil maken tussen de waardes van die velden (kijken odat er een veld is gewijzigd in de helpdesktool) en de indexen van fields niet gelijk aan elkaar zijn zoek ik deze op met tblVergelijkSD.FieldByName

Het gaat me op dit moment puur om het feit dat de waarde van i op 16 kan staan terwijl de grens op 15 ligt.
(Ben bezig om code door iemand anders geschreven om tezetten van Paradox naar MS-SQL)

Heah what?!?? O, signature??


Verwijderd

Zie mijn edit ;)

Voor de rest.. wat doet die addnote? Krijg je nog noemenswaardige foutmeldingen als je dat try except blok weghaalt?

  • remier
  • Registratie: Maart 2000
  • Laatst online: 06-04-2023

remier

Tired of spam?

Topicstarter
Als er een mutatie (bv. ander versienummer) heeft voorgedaan in de tussen tijd dan voegt AddNote het volgende toe in de table Notities:

code:
1
2
3
4
5
6
7
8
9
----- BIANCA @ 02-09-2004 - 11:04:30 -----
Omschrijving > "" = "in filter geen bedrijfsplaatsen en particulier"

----- BIANCA @ 02-09-2004 - 11:04:54 -----
met haar filter angepast en deze bijgevoegd

----- BIANCA @ 02-09-2004 - 11:05:13 -----
Behandeld_op > "" = "02-09-2004"
Status > "Open" = "Afgehandeld"

Heah what?!?? O, signature??


Verwijderd

remier schreef op woensdag 15 december 2004 @ 17:06:
Als er een mutatie (bv. ander versienummer) heeft voorgedaan in de tussen tijd dan voegt AddNote het volgende toe in de table Notities:
Ok, welke tabellen gebruikt hij daarbij? Voert hij nog iets uit met de database?

Als je het hele gedeelte tussen de try .. except gewoon weghaalt, doorloopt hij het dan wel goed, zonder i=16?

  • marrik
  • Registratie: Augustus 2003
  • Laatst online: 20-07-2025

marrik

Live long and prosper

Misschien erg obvious hoor, maar weet je 100% zeker dat het 16 velden zijn? En niet 17 (0 t/m 16)?
Probeer eens:

code:
1
showmessage(inttostr(tblSupportDesk.Fields.count-1));


Voor je loop.

Marrik


Verwijderd

Als je kijkt naar het plaatje wat hij gepost heeft, staat daar duidelijk dat het aantal 16 is (de watches) :P

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

De optimizer van Delphi kan besluiten dat de loop counter (in dit geval i) anders gaat lopen en daarbij wordt de loop counter gecorrigeerd bij het uitvoeren van de code in de for loop. Dat zou kunnen verklaren wat je ziet, maar zou niet voor een probleem mogen zorgen. Zet anders de optimalizatie eens uit in je Project Options en zet eens een ShowMessage(IntToStr(i)) in de loop.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

/me heeft zo het vermoeden dat hij in die notes.add functie dezelfde tables gebruikte..

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 12:05

Tomatoman

Fulltime prutser

try..except is er niet voor niets. Het is bedoeld om fouten die je van tevoren kunt voorspellen netjes af te handelen. Het is NIET bedoeld om onverwachte fouten (bugs) te verbergen voor de gebruiker. Die denkt dan dat alles goed is gegaan, terwijl er in feite een probleem is opgetreden en hij daar niets van heeft gemerkt. Een lege try..except is daarom bijna altijd een gevalletje slecht programmeren.

Haal in jouw gewoon de hele constructie weg, dan werkt alles zoals het hoort (dus inclusief foutmelding voor de gebruiker als er wat misgaat).

Een goede grap mag vrienden kosten.


Verwijderd

tomatoman schreef op woensdag 15 december 2004 @ 19:49:
try..except is er niet voor niets. Het is bedoeld om fouten die je van tevoren kunt voorspellen netjes af te handelen. Het is NIET bedoeld om onverwachte fouten (bugs) te verbergen voor de gebruiker. Die denkt dan dat alles goed is gegaan, terwijl er in feite een probleem is opgetreden en hij daar niets van heeft gemerkt. Een lege try..except is daarom bijna altijd een gevalletje slecht programmeren.
Zoals ik al zei, het try .. except blok is gewoon smerig.

Toch betwijfel ik dat het daar in zit. Immers, als je gewoon een default Delphi hebt, stopt de IDE ook op errors in een try .. except loop. Hij had dan wel een foutmelding gekregen, gok ik..
Haal in jouw gewoon de hele constructie weg, dan werkt alles zoals het hoort (dus inclusief foutmelding voor de gebruiker als er wat misgaat).
Misschien heeft hij niet de volledige code gepost, en is er wel foutafhandeling in het except .. end gedeelte. Althans, dat hoop ik dan maar ;)

Verwijderd

Verwijderd schreef op woensdag 15 december 2004 @ 19:26:
/me heeft zo het vermoeden dat hij in die notes.add functie dezelfde tables gebruikte..
Zou niet mogen uitmaken, ik neem tenminste niet aan dat het aantal velden veranderd in die functie :)

Maar wat gebeurt er als je dit doet
Delphi:
1
2
3
4
5
J:=tblSupportDesk.Fields.Count;
For I:= 0 to J-1 do
begin

end;
Misschien heeft hij niet de volledige code gepost, en is er wel foutafhandeling in het except .. end gedeelte. Althans, dat hoop ik dan maar
Hij kan ook de try except gebruikt hebben om te zien of de code wel stopt bij 16 en niet doorloopt tot 17,18 enz.

[ Voor 25% gewijzigd door Verwijderd op 15-12-2004 20:03 ]


  • remier
  • Registratie: Maart 2000
  • Laatst online: 06-04-2023

remier

Tired of spam?

Topicstarter
Verwijderd schreef op woensdag 15 december 2004 @ 20:00:
[...]


[...]

Hij kan ook de try except gebruikt hebben om te zien of de code wel stopt bij 16 en niet doorloopt tot 17,18 enz.
Ja zoiets had ik al geprobeerd:

Fieldcount := tblSupportDesk.Fields.count-1;

for i:=0 to Fieldcount do

Komt ook weer uit dat i 16 wordt :?


edit: Ik zal morgen weer eens gaan kijken op me werk, zoals al gezegd die code heb ik niet verzonnen ik moet heel die Helpdesktool porten van Paradox naar MS-SQL wat voor heel veel leuke problemen zorgt :D (afgezien van het feit dat er nergens commentaar bij staat...)

[ Voor 49% gewijzigd door remier op 15-12-2004 20:18 ]

Heah what?!?? O, signature??


Verwijderd

remier schreef op woensdag 15 december 2004 @ 20:13:
[...]

Ja zoiets had ik al geprobeerd:

Fieldcount := tblSupportDesk.Fields.count-1;

for i:=0 to Fieldcount do

Komt ook weer uit dat i 16 wordt :?
Niets van aantrekken. Dit is de Optimizer die hier aan het werk is.
Je code wordt binair omgezet om af te tellen naar 0 toe. Dus in weze wordt er als er als volgt geteld: 16 15 14 ... Dit heeft geen invloed op je code.

Je kan de weergave dacht ik wel goed krijgen / of het was een bug?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Verwijderd schreef op woensdag 15 december 2004 @ 20:00:
Maar wat gebeurt er als je dit doet
Delphi:
1
2
3
4
5
J:=tblSupportDesk.Fields.Count;
For I:= 0 to J-1 do
begin

end;
De eind conditie (J-1 of tblSupportDesk.Fields.Count - 1) wordt toch maar 1x opgevraagd, dus dat zal niets uitmaken.

We adore chaos because we like to restore order - M.C. Escher


  • remier
  • Registratie: Maart 2000
  • Laatst online: 06-04-2023

remier

Tired of spam?

Topicstarter
LordLarry schreef op woensdag 15 december 2004 @ 21:59:
[...]


De eind conditie (J-1 of tblSupportDesk.Fields.Count - 1) wordt toch maar 1x opgevraagd, dus dat zal niets uitmaken.
Waarom is dan (tblSupportDesk.Fields.Count - 1) waar volgens de watch altijd 15 uitkomt (16-1) niet hetzelfde als for I:=0 to 15 ? ;) :?

Heah what?!?? O, signature??


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Omdat de watch je aan het foppen is, vermoed ik. Zoals ik al zei vermoed ik dat de optimizer hier bezig is en die kan de debugger in de war brengen.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Verwijderd schreef op woensdag 15 december 2004 @ 20:00:
Zou niet mogen uitmaken, ik neem tenminste niet aan dat het aantal velden veranderd in die functie :)
Dat hangt er van af wat hij doet met die tabellen uiteraard. Het is mogelijk een tabel met minder velden te maken hoor, als hij er bv. een andere dataset aan koppelt.
remier schreef op woensdag 15 december 2004 @ 22:05:
Waarom is dan (tblSupportDesk.Fields.Count - 1) waar volgens de watch altijd 15 uitkomt (16-1) niet hetzelfde als for I:=0 to 15 ? ;) :?
Daarom denk ik dat de tabellen gewijzigd zijn. Normaliter zou dat niet mogen uitmaken (omdat hij die waarde idd. maar één keer ophaalt) maar na optimalisaties kan dat wel eens anders zijn.

In for .. next zit iig. geen bug. Ik heb er al 10000-den gezien die allemaal probleemloos werkten. Dus moet het in de code zitten.

Aangezien het stuk wat hij hier post er goed uitziet (afgezien van die smerige try .. except constructie) moet het ergens anders zitten. Die notes.add functie is dan de aangewezen kandidaat imo. Ik durf te wedden dat als je die even wegcommentarieert, dat het probleem zich dan niet meer voordoet..

Die procedure zit niet toevallig in dezelfde scope, en gebruikt ook een for..next met i ofzo?

[ Voor 5% gewijzigd door Verwijderd op 15-12-2004 22:19 ]


Verwijderd

LordLarry schreef op woensdag 15 december 2004 @ 21:59:
[...]


De eind conditie (J-1 of tblSupportDesk.Fields.Count - 1) wordt toch maar 1x opgevraagd, dus dat zal niets uitmaken.
Klopt :(

Wat misschien werkt is tblSupportDesk.FieldCount -1 Zelf nooit problemen mee gehad maar goed ADO is toch niet echt mijn ding :)

  • remier
  • Registratie: Maart 2000
  • Laatst online: 06-04-2023

remier

Tired of spam?

Topicstarter
ik heb er maar een ''for i:=tblSupportDesk.Fields.count-1 downto 0 do'' van gemaakt, dat werkt wel.
Maar het blijft allemaal maar vaaaag :7


edit:

Die ChangeNote.add voeg je de wijzingen toe aan een StringList, vervolgens sla ik die na bovenstaande code op:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
      if ChangeNote.count > 0 then
      begin
        //maak een notitie als er iets in s staat.
        TblNotities.Insert;
        TblNotitiesHelpdeskpunt.Value:= TblSupportDeskCounter.value;
        TblNotitiesSubmitter.Value:= sUser;
        TblNotitiesTijd.Value:= Time;
        TblNotitiesDatum.Value:= Date;
        TblNotitiesKind.value:= 'CNote';
        TblNotitiesLines.Value:= ChangeNote.text;
        TblNotities.Post;
      end;


Zoals je ziet doet deze niets met de tabellen waarbij ik de FieldCount gebruik maar met TblNotities.


Maar met de downto kan ik iig verder _/-\o_

[ Voor 121% gewijzigd door remier op 16-12-2004 09:31 ]

Heah what?!?? O, signature??

Pagina: 1