-
Content Count
1428 -
Joined
-
Last visited
-
Days Won
141
Everything posted by Stefan Glienke
-
FYI - Several Embarcadero services are currently unavailable
Stefan Glienke replied to Keesver's topic in General Help
Did you know that LEGO and Michelin are competitors? They both manufacture tires... -
Same GUID used in interfaces, is there any purpose for this?
Stefan Glienke replied to HaSo4's topic in RTL and Delphi Object Pascal
That was the point to show how it gives you the wrong one if two interfaces have the same GUID. The interfaces and their implementation in the RTL inherit from each other so their IMT overlap and the implementations don't differ between those two so there is does not matter. Simply try that for yourself by inheriting one of the interfaces in my example from the other. -
FYI - Several Embarcadero services are currently unavailable
Stefan Glienke replied to Keesver's topic in General Help
How some other company monitors their package manager. -
Same GUID used in interfaces, is there any purpose for this?
Stefan Glienke replied to HaSo4's topic in RTL and Delphi Object Pascal
RTTI does have nothing to do with it but TObject.GetInterfaceEntry - try the following code: type IFoo = interface ['{5DEC09C5-FADC-46A5-814F-9ED91259A37F}'] function GetFooName: string; end; IBar = interface ['{5DEC09C5-FADC-46A5-814F-9ED91259A37F}'] function GetBarName: string; end; TFooBar = class(TInterfacedObject, IFoo, IBar) function GetFooName: string; function GetBarName: string; end; function TFooBar.GetFooName: string; begin Result := 'Foo'; end; function TFooBar.GetBarName: string; begin Result := 'Bar'; end; var i: IInterface; begin i := TFooBar.Create; Writeln((i as IFoo).GetFooName); Writeln((i as IBar).GetBarName); end. The interesting thing with those two interfaces in the RTL is that coincidentally they will not cause any harm because of how they are implemented and related to each other - the one inherits from the other and they are also implemented by classes that inherit from each other. -
İs possible same pointer size for Win32/Win64?
Stefan Glienke replied to kosovali's topic in Algorithms, Data Structures and Class Design
Just store Pointer as UInt64 all the time -
Reported as RSP-44066
-
FWIW there is already this issue with 171 upvotes - it explicitly mentions Raspi but that would be a start. Given that Allen Bauer already had some kind of prototype ready in 2015 it's a shame Embarcadero never moved that forward.
-
I don't know what web finds you are referring to but afair they had been called Initialize and Finalize from the beginning when they were actually released - see https://docwiki.embarcadero.com/RADStudio/Sydney/en/Custom_Managed_Records They initially planned them for 10.3 but they were dropped shortly before because they were even more broken than at the time they got released in the version after - at that time the syntax was different but as said this was never released https://blog.marcocantu.com/blog/2018-november-custom-managed-records-delphi.html
-
Introducing "Uses Helper" - some little but incredibly helpful IDE plugin https://delphisorcery.blogspot.com/2021/03/introducing-delphi-uses-helper.html
-
Record operator overloading error
Stefan Glienke replied to lisichkin_alexander's topic in RTL and Delphi Object Pascal
Reported as RSP-44059 -
Create a new instance of a generic class
Stefan Glienke replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
Sorry, I meant _ClassCreate - the compiler inserts a call to that routine in the prologue of each ctor. When calling the ctor on a class the compiler passes 1 as the second parameter which signals this routine to call TObject.NewInstance. -
Create a new instance of a generic class
Stefan Glienke replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
You can trick/hack a bit and do what you want to achieve manually: This is basically what a regular ctor call on the class type does (see System._ClassCreate). function TSomeClass<T>.CreateNewInstance: ISomeInterface<T>; var obj: TSomeClass<T>; begin obj := TSomeClass<T>(ClassType.NewInstance); obj.Create(fSomeParameters); Result := obj; end; -
We use DUnitX and it discovers all our silly mistakes before release
Stefan Glienke replied to Lars Fosdal's topic in DUnitX
The irony about this is that to build a RAD application you are using components that are by design loosely coupled and more or less easily testable in isolation. The issue starts with non-UI-related code written directly into UI control event handlers and accessing global states such as these global form variables. If one would write their RAD application also in a component-driven architecture, things would be way easier - but slapping code into event handlers is quick at first and a nightmare to maintain later. -
Spring4D TPropertyChangedEventArgs example
Stefan Glienke replied to Dave Novo's topic in Delphi Third-Party
There is no magic, you implement INotifyPropertyChanged and raise events in setters. -
Fixed. You should be grateful that the CE is released at a point where it's the least broken version you can get.
-
RandomRange - just saying
-
IntToStr algorithm (Interesting read)
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
I don't know what to think after reading that article. Here are my comments on it: - the classic way of truncating the last 2 digits with div and mod 10 (or 100) does not involve a costly div or mod instruction on modern compilers (*cough* even Delphi 12 now does it - apart from the bugs that came with it) - I think C++ compilers would detect doing a div and a mod instruction and the code they emit would be further optimized so it does not require the "workaround" that the Delphi RTL uses by calculating the modulo by subtracting the div result times 100 from the original value. - the pseudo-code he shows for detecting the number of digits is correct but this is never what gets executed - and you either rewrite this into a few branches (as you can see in the RTL), a C++ compiler might unroll the loop or some other trickery is applied The DivBy100 function was introduced by me in RSP-36119 and I already notified them that DivBy100 can be removed in 12 because now it properly optimizes a div by 100 - however, that affects performance only by like 0.5% or so. As David correctly pointed out the real bottleneck is the heap allocation - and not only a single one when you just turn an integer into a string and display that one but when you concat strings and numbers the "classic" way because then it produces a ton of small temporary strings. That issue even exists when using TStringBuilder where one might think that this was built for optimization. If you look into some overloads of Append you will see that it naively calls into IntToStr and passes that down to the overload that takes string. This is completely insane as the conversion should be done directly in place into the internal buffer that TStringBuilder already uses instead of creating a temporary string, convert the integer into that one, pass that to Append to copy its content into the buffer. This will likely be my next contribution as part of my "Better RTL" series of JIRA entries. -
It's not, what you refer to is AOT - when .NET code runs, the runtime always JITs the code to machine code - read someone explain it who knows more than I do. You are mixing things here - I can also compile to native code with VC++ and still require some special version of the Visual C++ runtime to be installed.
-
You do realize that Java and C# are not interpreted like Python, yes? They compile down to machine instructions but not at compile time but at runtime - hence the term JIT. And fwiw the code that these JIT compilers produce often runs circles around what Delphi does with its ancient instruction set the compiler knows of. I am getting tired of that mantra "But it compiles to native code!" as if that in itself was something good. If that native code is poorly optimized and mostly looks the same as in '95 or compiled with -O0 then how good can it be?
-
PSA: Looks like that integer division is broken in 12 due to implementing this feature request. There are at least two reports already about this: https://quality.embarcadero.com/browse/RSP-43274 https://quality.embarcadero.com/browse/RSP-43418 Personally, I would say this absolute "need a hotfix asap" severity. I am honestly really sad about this because this encourages everyone who shies away from requesting any improvements to the compiler because it is almost certain that s**t will fall apart after. 😒
-
What you actually want to say is that the register allocator is bad (and that also applies to Win64) - which I agree with and has been reported repeatedly. However, pointing out one of the thousands of different specific cases is not getting us anywhere. Especially since there are way more impactful situations where this causes excessive stack spilling.
-
That code only wastes 2 bytes of binary code because the CPU will most likely apply register renaming and mov elimination (yes, there is some cost for decoding the unnecessary mov). But from all the possible optimizations in the x86 and x86-64 codegen this is one of the least important ones I can think of. FWIW x86-64 code will emit the lea instruction for both.
-
What? NativeInt is basically Int64 on a 64-bit target platform.
-
I do, but I know a dozen other things I would rather like to have, and know most of them have been reported for almost a decade or longer and nothing has happened about them - such as this no-brainer.
-
It's cute that you only have x86 in mind when discussing this.