Jump to content

David Heffernan

Members
  • Content Count

    3711
  • Joined

  • Last visited

  • Days Won

    185

Posts posted by David Heffernan


  1. 2 hours ago, Erik@Grijjy said:

    Glad you like it, and thanks for pointing out this issue. It only happens when you compile with Overflow Checking turned on. The hash functions I use should be compiled with overflow checking turned off, so I just added an {$OVERFLOWCHECKS OFF} directive to the Neslib.Xml.Types unit. Could you pull the latest version and try again?

    Would be nice to localise the disabling of overflow checks to just the hashing routines. 

    • Like 4

  2. 13 minutes ago, Kas Ob. said:

    Like there wasn't bugs in life of Delphi compilers.

    Sure. But there has never been a compiler bug where this particular language contract was not respected.

     

    You say that you have seen the compiler generate code which evaluates for loop ranges more than once. But that's incorrect. You have not seen that because no version of Delphi has ever had such a bug.

    14 minutes ago, Kas Ob. said:

    It was an advice and it will make sure it will be consistence, for loop limit after evaluation will be anyway stored as local variable, so no harm there.

    My point is that it is poor advice, a canonical example of FUD. 

     

    15 minutes ago, Kas Ob. said:

    As i said, it mainly concern when later you change the code from "for" to "while" loop.

    For sure it's worth knowing that while loops are different. Proficient Delphi programmers do know this, and are alive to this whenever they make choices of which loop to use.


  3. 1 hour ago, Kas Ob. said:

    I would not trust the compiler to generate one evaluation everywhere, i have seen this

    You have not seen this. The classic for loop evaluates the loop ranges exactly once. This is contracted by the language. 

     

    http://docwiki.embarcadero.com/RADStudio/Sydney/en/Declarations_and_Statements_(Delphi)#For_Statements

     

    "For purposes of controlling the execution of the loop, the expressions initialValue and finalValue are evaluated only once, before the loop begins."

     

    This sort of FUD is not helpful to anybody. 

    • Like 1

  4. 1 minute ago, Alexander Elagin said:

    Yes, but the point was that one has to use the collection's Count property for indexing and never the Length of the internal array, as the array may have more elements (preallocated for possible expansion) than the real number of elements in the collection.

    There were two points in that post. The point about not using Length of the internal list is well made. 

     

    But my post reacts to the other point in that post which advocated taking a copy of Count into a local variable before the for loop. 

    • Like 1

  5. 2 hours ago, Dalija Prasnikar said:

    I think you are blowing this out of proportion.

    I think OP's takeaway was to use direct array access always. I'd say use it with specific intent only. 

     

    3 hours ago, Dalija Prasnikar said:

    Why?

    I'm dead against TList exposing its internal implementation details like that. 

     

    Anyway, the Delphi collection classes have been such a mess over the years with so many bugs I gave up on them a long time ago and use my own collection library. If you can't do that then it's hard to see past spring's collections. 

    • Like 1

  6. 10 minutes ago, Dalija Prasnikar said:

    It won't fully help you with accessing TList List property. Since List can have more items than actual number of items stored, you can access index at the end of array that will not trigger compiler range error, but you will be accessing items outside of TList Items range.

    Which is why accessing via Items is to be preferred unless there are very well understood extenuating circumstances, for instance, measurable and significant performance gains. 

     

    But in such a case I'd probably look to use a different collection. 


  7. Your interposer is effectively useless. When you call CardPanel.AddNewCard an instance of Vcl.WinXPanels.TCard is returned. No amount of casting can change that. You are just telling a big fat lie to the compiler. If you use as to cast then you will find out the runtime truth. 

     

    They issue here is that you are trying to change the instantiated type of the cards. But declaring a new type of card doesn't achieve that since that code lives in the panel class. It's therefore the behaviour of the panel class that you need to modify. 

     

    In order to get your card types created you should override GetCardClass. 

     

    http://docwiki.embarcadero.com/Libraries/Sydney/en/Vcl.WinXPanels.TCustomCardPanel.GetCardClass

     

    You could do that with an interposer for TCardPanel. 

     

    However, I wonder if perhaps the right thing to do is to stop using GUI controls to store data. GUI controls present data. They should not have knowledge of that data. Code outside of the control should be in charge of that. 

    • Like 3
    • Thanks 1

  8. 34 minutes ago, Mike Torrettinni said:

    In for loop, I was sure we don't need range checking, right? Of course when iteration is from 0 to Count-1 index, for TList.

    But, when you are iterating through custom indexes, I assume range checking would be needed - but I don't use TList that way - I have some example for arrays, which first makes sure FromIndex and ToIndex are within Low and High of array.

     

    Er, I mean the compiler option. You just switch it on and it finds defects in your code. 


  9. 2 hours ago, Mike Torrettinni said:

    Thanks, yes, in this case I always access valid index.

    Nobody ever sets out to access out of bounds. But it happens. It doesn't happen because you decided to have a go at accessing out of bounds in case you get away with it. It happens because it's a mistake.

     

    The point of range checking is to detect those programming errors before the user is exposed to them. Presumably you use range checking? 


  10. Wrong. The answer to my question is yes. 

    SubItems: TList<TSubItem>

    When you access the items, a function getter is called, and that's where the copy comes from. That function getter has to assign its result somewhere and the compiler makes a temporary local variable for it. Hence the record init etc. 

     

    Access the array directly and there will be no copy.

    aItem.SubItems.List[i]

    The const arg works as you expect. 

    • Like 1
    • Thanks 1
×