-
Content Count
1366 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Stefan Glienke
-
FastMM5 now released by Pierre le Riche (small background story)
Stefan Glienke replied to Günther Schoch's topic in Delphi Third-Party
I don't know about the particular piece of code but I absolutely second that - if you can avoid branching, please please do so - unfortunately neat and clean code (an innocent looking if or a loop) can easily turn into a performance drain. -
Rapid generics for Delphi2010+ Internal Error
Stefan Glienke replied to Ponzu's topic in RTL and Delphi Object Pascal
Some of the benchmark results are just eyewash fwiw -
RTTI info for TBytes using runtime packages
Stefan Glienke replied to Wagner Landgraf's topic in RTL and Delphi Object Pascal
Regardless the current typeinfo issue I would always check for typeKind = tkDynArray (and possibly even tkArray) and ElemType = Byte because then you can also handle any custom declared TMyBytes = array of Byte type. -
RTTI info for TBytes using runtime packages
Stefan Glienke replied to Wagner Landgraf's topic in RTL and Delphi Object Pascal
The types are assignment compatible. When you declare a variable of TBytes in one module and call a method from a runtime package that uses TBytes that code will compile and work. Just the typeinfo generated is different so if you do some RTTI work you get false results. -
RTTI info for TBytes using runtime packages
Stefan Glienke replied to Wagner Landgraf's topic in RTL and Delphi Object Pascal
The issue is that TBytes is an alias for TArray<Byte> - generic types being used across different modules have several implications such as that they manifest into each module with their own typeinfo being generated. Try this code for example: uses Rtti, SysUtils; var ctx: TRttiContext; begin Writeln(ctx.GetType(TypeInfo(TBytes)).QualifiedName); end. In a regular console application it will print: System.TArray<System.Byte> While you would assume that it should print: System.SysUtils.TBytes Now if you enable runtime packages for this console application and let it link with rtl you will get an ENonPublicType here. Every module that is using TBytes is not referencing some type that is declared in the RTL runtime package but emiting its own version of TArray<Byte> into its binary. Personally I think this is an issue with the compiler treating the declaration of TBytes = TArray<Byte> different from TBytes = array of Byte in terms of the typeinfo generated - I was sure there is a QP entry somewhere about it but I cannot find it right now. To further provide the proof that aforementioned assumptions of other posters are wrong use the following code with a console application linking with the rtl package: uses Rtti, TypInfo, Classes, SysUtils; var ctx: TRttiContext; begin Writeln(ctx.GetType(TBytesStream).GetField('FBytes').FieldType.Handle = TypeInfo(TBytes)); end. This will print FALSE as the typeinfo of the FBytes field which is of type System.SysUtils.TBytes in fact differs from the typeinfo generated for the usage of TBytes in the console application binary. In fact there does not even exist a type called TBytes but only System.TArray<System.Byte> as TBytes it just an alias as I said and the declaration TBytes = type TArray<Byte> is not legit and raises E2574 Instantiated type can not be used for TYPE'd type declaration -
Difference between Pred and -1
Stefan Glienke replied to John Kouraklis's topic in RTL and Delphi Object Pascal
Fun fact: you can omit the 3rd argument of Copy if you just want to cut from the beginning. -
Find record operators via Rtti?
Stefan Glienke replied to Vincent Parrett's topic in RTL and Delphi Object Pascal
https://bitbucket.org/sglienke/spring4d/src/409cf53e4848815ac089763243469226b363d3be/Source/Base/Spring.pas#lines-3806 -
Exception.CreateFmt vs. CreateResFmt
Stefan Glienke replied to dummzeuch's topic in RTL and Delphi Object Pascal
It gets bad if the implicit string or other managed type variables are the only of that type because then you get the implicit try finally added. And at least for win32 we know now that try/finally is implemented kinda badly: https://quality.embarcadero.com/browse/RSP-27375 -
Exception.CreateFmt vs. CreateResFmt
Stefan Glienke replied to dummzeuch's topic in RTL and Delphi Object Pascal
That is why for performance critical code such code should be moved to an extra (or nested) routine. Otherwise you get pro- and epilogue polluted with code that is not necessary in the majority of cases. Additional read: https://www.delphitools.info/2009/05/06/code-optimization-go-for-the-jugular/ -
Setting a "nullable" property on a .NET object
Stefan Glienke replied to Dave Nottage's topic in Windows API
Yes it is, it's a struct -
https://quality.embarcadero.com/browse/RSP-20169
-
Generics in Delphi have more severe issues that should be worked on than that tbf
-
spring4d list immidiately gets freed
Stefan Glienke replied to Rainer Wolff's topic in RTL and Delphi Object Pascal
FToollist is certainly not being freed but the items because the list returned by FindAll has OwnsObjects = True and goes out of scope at the end of the method. Write dm.Session.FindAll<TTool>.MoveTo(FToolllist); -
language updates in 10.4?
Stefan Glienke replied to David Schwartz's topic in RTL and Delphi Object Pascal
I would like to but I don't (and not because of FUD but because I know of the bugs myself) - do I need to say anything more? Ask around in other languages if people in general trust their compilers and standard runtime libraries or not. -
language updates in 10.4?
Stefan Glienke replied to David Schwartz's topic in RTL and Delphi Object Pascal
https://en.wikipedia.org/wiki/Hyperbole -
Generics and Classes on Windows 2000 = OOM
Stefan Glienke replied to aehimself's topic in General Help
Dynamic arrays cannot leak unless you circumvent the compiler generated code controlling their reference counting. -
FWIW just recently my coworker opened these issues that are related to this topic: https://quality.embarcadero.com/browse/RSP-27799 https://quality.embarcadero.com/browse/RSP-27802
-
language updates in 10.4?
Stefan Glienke replied to David Schwartz's topic in RTL and Delphi Object Pascal
VS is also not perfect but their compiler and language design is rock solid - yes, if you look into C# communties there are also people complaining that stuff is not C#-ish and that but the number of times where the C# compiler just craps itself, kills the entire IDE or simply produces completely wrong code is like several orders of magnitudes less than with Delphi. -
language updates in 10.4?
Stefan Glienke replied to David Schwartz's topic in RTL and Delphi Object Pascal
YES, exactly that! However many Delphi developers have a troubled past where often "new" things turned out to be broken, caused problems or were simply not thought through entirely and just slapped onto existing things like duck tape. Like using attributes like [ref] in addition to the existing keyword const just because of the fear to introduce new keywords or introducing inline variables (that had many bugs) without the entire tooling understanding them and stopping to work. So many people are in the mindset of "don't touch it so you can't break it" and "fix the existing bugs before adding new broken stuff" -
language updates in 10.4?
Stefan Glienke replied to David Schwartz's topic in RTL and Delphi Object Pascal
Interesting - even with {$mode delphi} it does not allow that - probably it's yet another of those bazillion switches of FPC to make it behave similar to Delphi - not that I would ever care. Anyhow this is still a thread about Delphi so your approach is not sufficient here imo. @Fr0sT.Brutal It's a little less simplistic than that but basically yes. -
As I wrote before a final method or sealed class will produce a non virtual call in your approach - try again the code from your original post with virtual in TTest1 and override final in TTest2. Also let me add that the fear of virtual method calls is way too high and in most cases it turns out they don't affect the overall performance at all (especially not with some code that the Delphi compiler produces that trashes your performance in other ways) If you call a virtual method in a tight loop and want to avoid the "virtual method address lookup" (again, measure if it really affects anything) that happens every time then you can store it as a method pointer before and then call that one in your loop.
-
Then you probably should read them again - they say: warning CS0114: 'TTest2.Test()' hides inherited member 'TTest1.Test()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
-
public new is not overriding - that's similar to reintroduce - if you want to override, you write *drumroll* override I would even guess the CLR to be clever enough to devirtualize it entirely
-
You make the Test method virtual just like was suggested in the 2nd post for the similar Delphi code. You can then even make the override in TTest2 final or make the class sealed and get a non virtual call generated by the compiler!
-
How about you write the code in a proper way: using System; public class TTest1 { public void Test() { Console.WriteLine("TTest1.Test"); } } public class TTest2: TTest1 { public void Test() { Console.WriteLine("TTest2.Test"); } } public class TTest<T> where T: TTest1, new() { public static void TestIt() { var FTest = new T(); FTest.Test(); } } public class Program { public static void Main() { TTest<TTest2>.TestIt(); } } The reason FPC does it different is because its generics are behaving more like C++ templates. However for generics there is no kinda "duck typing" or prototyping. You tell the generic class "look there is the type parameter T, which is guaranteed to be a TTest1 and it has a constructor". So when the compiler generates the AST for the generic type it just takes from these informations and so it decides to emit a static call to TTest1.Test because that is not a virtual method. This is the behavior in all languages with generics that I know of (such as C# or Java) - languages that use a templating approach such as C++ and possibly FPC does it similar decide what to call when the type parameter is being specified. Generics in this case behave the same way as if you would write code like this: procedure TestIt(const t: TTest1); begin t.Test; end; here it will always call TTest1.Test and not TTest2.Test even it t is a TTest2 - simply because there is no polymorphism happening due to the lack of a virtual method call. Personally I would rather call this a bug in FPC - but again it depends on the actual language specification/implementation. Both have their pros and cons. I cannot find the official specification for generics in FPC about this specific point to verify.