Jump to content

Stefan Glienke

Members
  • Content Count

    1366
  • Joined

  • Last visited

  • Days Won

    130

Everything posted by Stefan Glienke

  1. Stefan Glienke

    One more memory leak and FastMM4

    Solution: Pass TRefCounting.True to AsSingleton because otherwise the container uses a very basic way to determine if the instance is reference counted or not and that is often false if it was implemented by yourself. Explanation: The container needs to know that in order to store the instance served as singleton and properly destroy it in the end: - either by letting go the interface reference if it was reference counted - or calling Free on the object reference if it was not reference counted The issue has been open for a while now and I have a few ideas but it did not make it to the top of my priority list yet: https://bitbucket.org/sglienke/spring4d/issues/237 Alternative solution: If you are using the instance as singleton why implement reference counting in the first place - it makes no sense. By the way: Stop using so many delegates if all you do is resolve all the ctor parameters yourself - that defeats the purpose of using a DI container. If you want to force the DI container to use a certain ctor then put the [Inject] attribute over the ctor- then you will get a resolve exception when it could not provide all parameters. That might be important because by default the container falls back to a less greedy ctor if it cannot provide all parameters (you can configure that behavior) which sometimes lead to defects at it always ultimately falls back to TObject.Create (RTTI cannot see that it might not be visible because information about method overloading is not available) If you want to use a certainly named service to be injected then put the [Inject(<servicename>)] attribute on the specific ctor parameter. Another way would be to use InjectConstructor in the registration and provide the parameternames (at this time you have to specify all parameters - if you want to use the default service then pass TValue.Empty or nil) - I am working on being able to provide value/servicename for individual ctor parameters because that also makes things robust agains refactorings. The code you wrote actually serves no purpose at all - it would be shorter and faster if you used pure DI instead because with all the DelegateTo calls you basically did just that. If you put a parameterless ctor into your DM class which just calls inherited Create(nil); then you can get rid of all DelegateTo calls in your registration and just let the container do its job.
  2. Stefan Glienke

    GExperts supports even more laziness

    @Mahdi Safsafi Oh, yes that's probably inside the debugger that reacts to https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-debug_event - so one needs to probably go a little deeper there 😉
  3. Stefan Glienke

    GExperts supports even more laziness

    Run the IDE under the debugger - make it show that dialog - pause it and look into the call stack (need to look through several threads to find the correct one) - and eventually you will find it. Then simply hook that call and let it run through your code first. The tricky part is just doing this reliably for all supported versions
  4. Stefan Glienke

    GExperts supports even more laziness

    Hooking into the code that displays this dialog would probably do the job but is probably not trivial. I've had this request long ago when I started TestInsight because if you run your unit tests under the debugger and you obviously also have tests that check if the correct exceptions occur if you do something bad this will result in a lot of exceptions cought by the debugger. In that scenario however it would only not show those exceptions that you expected in your unit test but break on all others which makes it a bit more complex than just "clicking the dialog away"
  5. Stefan Glienke

    FreeAndNil 10.4 vs 10.3.1 and Pointers

    Refactoring away from objects to something else and forgetting FreeAndNil is probably the number one source of defects of this category which is why I am happy for this change in 10.4 even though it also has its quirks most notably an API that tells a lie.
  6. Stefan Glienke

    Your RAD Studio 10.4 Sydney issues

    FWIW - reported as https://quality.embarcadero.com/browse/RSP-29564
  7. Stefan Glienke

    Reproducible AV in Sydney

    Wrong place - report at https://quality.embarcadero.com/
  8. Stefan Glienke

    TFixedCriticalSection

    Print TCriticalSection.InstanceSize and you know if it was fixed or not - spoiler: no, it was not. On Windows that is - on Posix TCriticalSection simply uses System.TMonitor which allocates at least the size of a cache line
  9. Stefan Glienke

    When did Pos become PosEx?

    Delphi XE3 because I have this code in Spring.pas: {$IFNDEF DELPHIXE3_UP} function Pos(const SubStr, Str: UnicodeString; Offset: Integer): Integer; asm jmp PosEx end; {$ENDIF}
  10. Sorry to disappoint you but that does not compile but raises [dcc32 Error] E2574 Instantiated type can not be used for TYPE'd type declaration Too bad we are working with Delphi where it does not matter because I can still assign a TUserName to TUserFirstName
  11. Stefan Glienke

    Should Delphi have native interfaces?

    Yeah sure... Good luck with that - there are tons of more frequently asked and easier to design and implement features open for years. I am very certain that Bruneau had the C++ approach in his mind even though he mentioned .NET/Java (which have GC that Delphi does not have) because otherwise memory management would clash. And if I am not totally mistaken after a bit of search you cannot even implement more than one interface per class in C++ - but again my practical C++ experience is many years ago. Now C# and Java can implement multiple interfaces per class and under the hood interfaces are basically the same as classes just that you cannot instantiate them. But the compiler and the runtime know about all that - if you think Embarcadero can pull this off you must be new to the game.
  12. Stefan Glienke

    Should Delphi have native interfaces?

    There is no proposal - there is just a "it would be cool if" without any actual suggestions how something can be achieved. I asked a couple of questions but they have not been answered (or I missed those) that are important to decide if something like event<->interface method binding can be achieved and how it would look like. Currently any assignment of interface methods to an event would break reference counting similar to how anonymous methods can't be assigned to an event. One is a managed type, the other is a record with 2 raw pointers. Now we could all list stuff that would be cool to have without actually evaluating if that is technically possible - but to me that would be just a waste of time I could spend more productive.
  13. Stefan Glienke

    Should Delphi have native interfaces?

    It's mentioned in the "A bit of history" paragraph of the article you linked to yesterday - it's as if you write code like this if Sender is TComponent then //... do something else if Sender is TButton then //... do something else You clearly will never reach the code for TButton Clearly the interface inheritance clashes with the fact that you can implement a derived interface but not the base one. Probably this is why COM in .NET behaves a bit differently: https://social.msdn.microsoft.com/Forums/vstudio/en-US/7313191a-10db-4a16-9cdd-de9fb80b378a/com-interop-base-class-properties-not-exposed-to-com?forum=csharpgeneral
  14. Stefan Glienke

    Should Delphi have native interfaces?

    You know that bugs can be in implementation and also in design See this code: type IFoo = interface ['{1E77F313-1C93-4A59-957B-751FB23EC63F}'] procedure Foo; end; IBar = interface(IFoo) ['{49FC3BDA-7A09-4596-A80C-5EBEF73BA201}'] procedure Bar; end; TFooBar = class(TInterfacedObject, IFoo, IBar) public procedure FooFoo; procedure IFoo.Foo = FooFoo; procedure BarFoo; procedure IBar.Foo = BarFoo; procedure Bar; end; { TFooBar } procedure TFooBar.Bar; begin Writeln('Bar'); end; procedure TFooBar.BarFoo; begin Writeln('BarFoo'); end; procedure TFooBar.FooFoo; begin Writeln('FooFoo'); end; var bar: IBar; foo1, foo2: IFoo; begin bar := TFooBar.Create; bar.Foo; bar.Bar; foo1 := bar; foo1.Foo; foo2 := bar as IFoo; foo2.Foo; Readln; end. The Foo method is implemented differently for IFoo and IBar but depending on how I get an IFoo I get one or the other. Now we can run circles around this and argue back and forth - fact is that they clearly missed the opportunity to specify if you want to also let the compiler implicitly put the ancestors into the interface table as well if you really wanted to without explicitly writing them down - you have the implement the methods anyway.
  15. Stefan Glienke

    Should Delphi have native interfaces?

    You are avoiding to answer the important question that is the reason why this does not work with COM interfaces.
  16. Stefan Glienke

    Should Delphi have native interfaces?

    My thoughts: 2. modify QueryInterface to take care of looking through the implemented interfaces if any of them inherits from the requested if it was not implemented implicitly - or simply add base interfaces to the implementing class - not a big deal fwiw. 3. what exactly does that mean? 4. reference counting issue - a procedure of object is just two raw pointers - how does that mix with interfaces - now if those COM-free interfaces would not have reference counting implemented the problem I described previously arises which will make them rather pointless.
  17. Stefan Glienke

    Should Delphi have native interfaces?

    Yes! In the COM implementation and it was carried over to Delphi as a feature to make it work.
  18. Stefan Glienke

    Should Delphi have native interfaces?

    What you describe is exactly what traits are in Scala. Well minus the fact that traits can even declare fields but when they always implemented by objects that would work as well - hence I would not call them anything like "so and so interface" - because while they might be similar they would be a completely different beast and not to be mixed with them. Anyhow it would come down to no proper way to cleanup those things - Scala and all other languages that have similar things use GC so you will not have any headaches about when something has to be destroyed. If you pass around your objects as traits/ninterface/whatever with the memory management we currently have in Delphi this will just an even huger pain than you already have if you mix object and interface references to classes that either implement reference counting or not. P.S. If you are interested how Scala implements traits: https://www.nurkiewicz.com/2013/04/scala-traits-implementation-and.html
  19. Stefan Glienke

    Should Delphi have native interfaces?

    "Native Interface" is a terrible name tbh - what exactly would be "native" about it that current interfaces are not. A look at other languages might be helpful to actually define clearly what your desired requirements are - for example traits in Scala.
  20. Stefan Glienke

    Should Delphi have native interfaces?

    According to that logic IFooBar must not be assignment compatible to IBar - but it is. Even the compiler knows about this because actually if you implement IFooBar and IBar into the same class without any specific method resolution clauses it puts both IMTs into the very same slot (IBar shares it with the IFooBar one)
  21. Stefan Glienke

    Should Delphi have native interfaces?

    There is nothing logical about it - as the previously linked article says:
  22. @stk.List[stk.Count-1]
  23. Stefan Glienke

    TMemoryStream.Write

    Yes - because try finally (not only the implicit! ones) are implemented poorly and result in trashing the return stack buffer of the CPU all the time: https://quality.embarcadero.com/browse/RSP-27375 @Attila Kovacs The difference between the two IsBreak versions is most likely related to branch prediction and the difference between a conditional forward jump typically taken and not taken - if you want to read more about it I suggest this rather in depth article by Matt Godbolt: https://xania.org/201602/bpu-part-one As for performance of this nested function I would guess it could run even faster when it would not access anything from the outside because that usually requires quite some stack lifting. And having to do that usually prevents the compiler to have more than one exit point as was mentioned before - if there are no registers to pop and that the compiler neatly puts rets in different places though - but I would guess you will not get around that for this function but probably around repeatedly accessing the LineBreak property and variables P2 and LineBreakLen
  24. Stefan Glienke

    Meet a New EntityDAC with Support for Delphi 10.4

    @Lars Fosdal Marketing drivel.
  25. I can't see a situation where TArray<T> can have noticable overhead as it does not have enough stuff to be generated - what you demonstrated was using a generic class that has executable code and RTTI.
×