Jump to content


Popular Content

Showing content with the highest reputation on 06/28/22 in all areas

  1. Hm, wasn't the point of the first post in this thread that FreeAndNil isn't big enough of a subject to make a whole video about? Two pages of discussion say otherwise.
  2. I recently spent an entire week trying to fix a bug where in heavily threaded situations customers were seeing random av's. The av's and the stack traces were very random, which made it very difficult to pin down. Debugging threads in delphi is painful at best - any changes to timing can completely mask bugs so using breakpoints was not going to work (and the bug would occur in around 4 out of 40 identical threads). After spending days adding even more (pointless as it turned out) locks all over the show I wasnt' much closer to figuring it out. I suspected it could be a reference counting issue (since I use interfaces a lot), so started sprinkling some FreeAndNils around the code (in destructors) - suddenly those random av's turned into nil pointer exceptions that were much less random. That confirmed to me that the issue was with accessing objects already free'd. The problem turned out to be that I was using weak references where I really needed strong references - a 70hr week of frustration turned into a 4 line change 🤦‍♂️ I really don't understand all the angst and debate about FreeAndNil - use it where it makes sense, or don't - just like any other RTL function or language feature.
  3. Zero, I know it's not thread safe. It wasn't just freeandnil that solved the issue (if only). Just another tool in the box, which I used then removed. I still don't get why people get upset about FreeAndNil - I have much bigger and more important issues with delphi to deal with (like actual bugs in the ide/compiler/rtl/vcl) rather than worry about something so minor.
  4. Wrong solution. Right solution is to learn what you don't know how to do. No shortcut. Certainly not by just saying "use interfaces".
  5. As you say, that's a problem with the developer rather than the function itself. I personally use FAN everywhere and my debug builds use FastMM with all bells and whistles. There aren't downsides to using FAN and it does make it easier to catch some defects.
  6. Using FastMM with the setting to mark freed memory with a certain pattern ($80808080 by default iirc) would have revealed that issue within a few minutes fwiw.
  7. I don't realize the problem at all. FaN pro's - it could help find bugs and is useful for lazy init. Con's - procedure use instead of a method? Duh. Insignificant for me. I see no reasons to not use FaN everywhere,
  8. I did use that, and it got me closer, but not close enough.
  9. corneliusdavid

    Confusing marketing email from EMB

    Yeah, I get lots of emails like this, too, and just have to delete them. Those seconds glancing at emails add up each day (not being sarcastic). However, I can see Embarcadero wanting to send this out to everyone just on the off chance that: You have one product (Delphi or C++Builder) and have been thinking of getting the other one, or.. You might want to upgrade your current subscription, or ... You know of someone that is ready to purchase but hasn't done it yet and they're not on the mailing list. A couple of years ago, I was a current subscriber of the Professional edition and I took advantage of one of these offers to upgrade to the Enterprise edition. It was considered a new purchase because I did not currently have the Enterprise edition so I qualified for the advertised sale but I was able to get an additional discount because I upgraded from the Professional edition. So in some cases, these sales can even be good for existing customers.
  10. Dalija Prasnikar

    Weak reference is dangerous

    Assignment operation in Delphi are not thread safe. If you have one thread writing and other threads reading, such access must be protected or you will get crashes or buggy behavior. You can safely write and read 32bit aligned simple types, in terms that such code will not cause any crashing, but such code will also not work as intended, unless you don't care about actual values stored. So, weak references in Delphi are not thread safe. Also even strong interface references in Delphi are not thread safe. So there is no bug here, just bad test case. Excerpt from my book Delphi Event-based and Asynchronous Programming (Part 5. Thread Safety) If you have multiple threads accessing - reading and writing - the same reference, one thread can easily interfere with the other. Let's say we have a shared interface reference `Data`, pointing to a previously created object, one thread that sets that reference to nil, and another thread that tries to take another strong reference from that one with an assignment to another variable `Tmp`. The first thread will execute the `_IntfClear` function that will result in object destruction. The second thread, trying to grab a strong reference preventing object destruction, will execute the `_IntfCopy` function: var Data, Tmp: IInterface; Data := nil; // Thread 1 -> _IntfClear Tmp := Data; // Thread 2 -> _IntfCopy If the `Source._AddRef` line from the `_IntfCopy` function executes before the call to `IInterface(P)._Release` manages to decrease the reference count to zero and subsequently calls the object's destructor, all is good. The second thread will successfully capture another strong reference to the object instance. However, the first thread can interrupt the second thread at the wrong moment, just after the `Source <> nil` check was successfully passed, but before `Source._AddRef` had the chance to increment the object's reference count. In that case, the first thread will happily destroy the object instance while the second thread will happily grab a strong reference to an already nuked object, and you can forget about happily ever after. Note: Besides interface references to objects, the reference counting mechanism is also used for other types like strings and dynamic arrays. Assignment of those types is also not thread-safe.