XE7 and more With weirdness

XE7 and more With weirdness

100% reproducable fail: Access violation at address 00B5464D in module ‘MyApp.exe’. Read of address 00000040.

Fails:

    tpLot := Tp.Add;

    with tpLot do

    begin

      LotId := Lot.Id; // <–BANG

      LotNo := Lot.LotNumber;

      ExpiryDate := Lot.ExpireDate;

      ProducedDate := Lot.ProducedStartTime;

      ArticleId := ArtSum.ArticleId;

      ArticleNo := ArtSum.ArticleNumber;

      OriginalArticleId := ArtSum.ArticleId;

      Quantity := NumDPacks * ArtSum.BaseUnitsPerKPack;

      NetWeight := Quantity * ArtSum.NetWeightPrBaseUnit;

      GrossWeight := NetWeight +

        (ArtSum.TaraWeightPrFPack * Quantity);

      LotLockState := Lot.LockStateCode;

    end;

Works:

    tpLot := Tp.Add;

    tpLot.LotId := Lot.Id;

    tpLot.LotNo := Lot.LotNumber;

    tpLot.ExpiryDate := Lot.ExpireDate;

    tpLot.ProducedDate := Lot.ProducedStartTime;

    tpLot.ArticleId := ArtSum.ArticleId;

    tpLot.ArticleNo := ArtSum.ArticleNumber;

    tpLot.OriginalArticleId := ArtSum.ArticleId;

    tpLot.Quantity := NumDPacks * ArtSum.BaseUnitsPerKPack;

    tpLot.NetWeight := tpLot.Quantity * ArtSum.NetWeightPrBaseUnit;

    tpLot.GrossWeight := tpLot.NetWeight + (ArtSum.TaraWeightPrFPack * tpLot.Quantity);

    tpLot.LotLockState := Lot.LockStateCode;

Lot and ArtSum are properly initated and readable (inspected in debugger), so I assume it is the assignment that fails.

The problem is, I cannot reproduce in a mini-example.

If I wasn’t set at eradicating all with statements before, I surely am now.

 

14 thoughts on “XE7 and more With weirdness


  1. I thought we all agreed “with” was a Bad Thing. 😉  I have, in other versions, seen errors thrown when you qualify a member inside the “with” with the item assigned in the “with”. Messy writing about that…


  2. We did agree, and it still is.  It just takes time to get rid of all that has accumulated over the years.  But a single with reference failing? That’s bad!


  3. Lars Fosdal Be wary you might just be getting rid of the canary, or shooting the messenger, or breaking the thermometer 😉


    Everything else being correct, this failure could just be a sign of other memory corruption/stack overwrites, and removing the “with” hides that issue under the carpet.


    The fact you cannot reproduce it in a simpler case is another hint in that direction.


    Inspect in the asm/CPU view, and debug the state there: if there is a memory corruption of some sort, the higher level debugger is unreliable.


    Then, once that’s solved, get rid of the “with”.


  4. Walter Prins – Did that, and it’s solid.


    It was the assignment side that was broken.


    One thing I just noted – tpLot.LotNo had duplicates in the procedure parameters, but the with parameter should “out-scope” those.


    procedure SomeClass.DoThis(const ArticleNo, LotNo: String);


    var


      Lot: TLot;


      ArtSum: TArticleSummary;


      tp: TPack;


      tpLot: TPackLot;


    begin


      ArtSum := ArtSummaries.Locate(ArticleNo);


      Lot := Lots.Locate(LotNo);


      tp := TPack.Create;


      tpLot := tp.Add;


      with tpLot


      do begin


        LotId := Lot.Id;


        LotNo := Lot.LotNumber;


        ExpiryDate := Lot.ExpireDate;


        ProducedDate := Lot.ProducedStartTime;


        ArticleId := ArtSum.ArticleId;


        ArticleNo := ArtSum.ArticleNumber;


        OriginalArticleId := ArtSum.ArticleId;


        …


  5. Given that Lot already is a local var, and not in duplicate with anything else, and found and returned by the locator – that seems far fetched.


    I’d give it a spin, but I’ve consumed all the testable data I received. I’ll check  with the warehouse peeps if they can send me more pallet labels.


  6. What you state doesn’t tally with my understanding of scope. The variables brought into scope by that with are searched first. So the code emitted should be identical. The fact that you cannot make a repro suggests that the issue is on your end.


  7. David Heffernan – When I put a breakpoint on the first assignment, I can inspect all properties of Lot, but when I do F8 to step to next line – I get the exception.  If the right side of the assignment was the issue, why does the problem go away when I take out the left side With?


    Unless the code generated is for assigning to a const LotNo string, and that somehow fails – which also would be a compiler error.


  8. Bill Meyer I agree. With is evil. The small optimizations perhaps generated by the compiler are not worth the frustrations. Having manned Borland’s help desk. I could testify…

Leave a Reply