tag:blogger.com,1999:blog-44716830110004313532024-03-09T01:11:50.048+01:00Delphi Corner WeblogThis is the blog for Rudy Velthuis' <a href="http://rvelthuis.de">Delphi Corner</a>.Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-4471683011000431353.post-55618792076308165462019-05-01T22:25:00.000+02:002019-05-03T09:44:59.025+02:00Case sensitivity<p>Found this piece of code in a message (now deleted) on Stack Overflow, for the language Go:</p>
<pre>
<b>func</b> addGmp(a, b, c, d, e, f, x, y, X, Y, P *big.Int) (*big.Int, *big.Int) {
<i>// a,b,c,d,e,f this var (fast in func)</i>
a.Sub(Y, y)
b.Sub(X, x)
...
</pre>
<p>The problem is not only that all the parameters have single-letter names that don't say anything about them, the much bigger problem is that there are parameters named <code>x</code> and <code>y</code> as well as <code>X</code> and <code>Y</code>. This is, IMO even worse than something like (in C):
<pre>
<b>int</b> SomeApi(HWND hwnd, HDC hdc);
</pre>
<p>Let me reiterate that I am so happy that Delphi (and Pascal) are case-insensitive, and that such abominable parameter names are not possible.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com2tag:blogger.com,1999:blog-4471683011000431353.post-48550552686735226212019-02-27T00:57:00.001+01:002019-02-27T01:06:08.498+01:00New in Rio: custom PRNG<p>I don't know if anyone noticed, but there is something new in the System unit of Delphi 10.3 Rio
that is not documented yet.</p>
<p>In Rio, if you want to improve the default pseudo random number generator (PRNG), you can now supply
your own 32 bit random function. There is a procedural variable, <code>Random32Proc</code> of type
<code>function: UInt32</code>, to which you can assign your own random function. <code>Random</code> will call
this function to get a new random value instead of the default function.</p>
<p>The default setting of this variable is <code>System.DefaultRandom32</code>. This is the same as
the old Delphi PRNG.</p>
<p>Because your new function may need a different way to set the random seed too, there is
something similar for Randomize: <code>RandomizeProc</code>.</p>
<p>Here is the corresponding part of <em>System.pas</em>:</p>
<pre>
<i>{ random functions }</i>
<b>type</b>
TRandom32Proc = <b>function</b>: UInt32;
TRandomizeProc = <b>procedure</b>(NewSeed: UInt64);
<b>function</b> DefaultRandom32: UInt32;
<b>procedure</b> DefaultRandomize(NewSeed: UInt64);
<b>var</b>
Random32Proc: TRandom32Proc = DefaultRandom32;
RandomizeProc: TRandomizeProc = DefaultRandomize;
<b>procedure</b> Randomize;
<b>function</b> Random(<b>const</b> ARange: Integer): Integer; <b>overload</b>;
<b>function</b> Random: Extended; <b>overload</b>;
</pre>
<p>I tried this with the XorShift implementation in my
<a href="https://github.com/rvelthuis/DelphiBigNumbers/blob/master/Source/Velthuis.XorShifts.pas">DelphiBigNumbers GitHub repository</a>
and it worked as expected.</p>
<p><strong>Much fun with this!</strong></p>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-54020711795365629422019-02-02T14:00:00.005+01:002019-02-02T14:18:09.014+01:00Delphi-Praxis.net<p>Just a short thanks.<p>
<p>I personally still prefer Usenet-like NNTP newsgroups and a newsreader like <strong>XanaNews</strong>, Forté Agent, Gravity or even Mozilla Thunderbird over any web-based forums.</p>
<p>But since we don't have those anymore, I would like to thank the fine people at <a href="https://en.delphipraxis.net/" target="_blank">Delphi-Praxis.net</a>. They have done an excellent job replacing the various Google+ as well as the old Embarcadero forums. They have created a well balanced set of groups to discuss things pertaining Delphi and C++Builder.</p>
<p>Sure, there is the new <a href="https://community.idera.com/developer-tools/p/forums" target="_blank">Idera Community</a>, the official replacement for the Embarcadero forums, but I think the Delphi-Praxis.net forums have a, je ne sais quoi, different "feel" to it.</p>
<p>Note that both platforms require you to sign up. I am pretty sure that helps (a little) keeping away the spam and other unwanted input.</p>
<p>If you haven't, go and visit the place. It is a good one. (Also visit the Idera forums, and see which you prefer. I regularly visit both.)</p>
<p>Also recommended:</p>
<ul>
<li><a href="https://www.beginend.net/" target="_blank">begin end</a></li>
<li><a href="http://www.delphifeeds.com/" target="_blank">DelphiFeeds</a>.</li>
</ul>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com3tag:blogger.com,1999:blog-4471683011000431353.post-2849456507204404282018-10-30T00:20:00.000+01:002018-10-30T19:29:21.490+01:00Inline declaration of variables<p>There will be a new interesting feature in the upcoming Delphi 10.3 Rio: inline declared variables. I have permission to blog a little about it.</p>
<p>Marco Cantù already <a href="http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+marcocantublog+%28marcocantu.blog%29">wrote about this new feature</a>. I am not going to explain it, as I think he already did a good job doing that.</p>
<p>I just want to demo one of the main advantages of them: they are block-local, i.e. they are initialized at the point of declaration and are finalized at the end of the <code>begin</code>-<code>end</code> block they were declared in. This means that an interface or other managed variable declared that way is finalized at the end of the block.</p>
<p>To demo this, I made a little talkative interface, which tells us what it is doing, and when it is being created and being destroyed. It also has a name. Here is the code:</p>
<pre>
<b>type</b>
ITalking = <b>interface
procedure</b> Talk;
<b>end</b>;
TTalking = <b>class</b>(TInterfacedObject, ITalking)
<b>private</b>
FName: <b>string</b>;
<b>public
constructor</b> Create(<b>const</b> Name: <b>string</b>);
<b>procedure</b> Talk;
<b>destructor</b> Destroy; <b>override</b>;
<b>end</b>;
implementation
<i>{ TTalking }</i>
<b>constructor</b> TTalking.Create(<b>const</b> Name: <b>string</b>);
<b>begin</b>
FName := Name;
Writeln(Format(<em>'Creating %s'</em>, [Name]));
<b>end</b>;
<b>destructor</b> TTalking.Destroy;
<b>begin</b>
Writeln(Format(<em>'Destroying %s'</em>, [FName]));
<b>inherited</b>;
<b>end</b>;
<b>procedure</b> TTalking.Talk;
<b>begin</b>
Writeln(Format(<em>'Hi, %s talking here!'</em>, [FName]));
<b>end</b>;
</pre>
<h2>Demo</h2>
<p>And here is the demo:</p>
<pre>
<b>procedure</b> Test;
<b>begin
var</b> I1: IInterface := TTalking.Create(<em>'One'</em>); <i>// one way to declare an interface</i>
Writeln(<em>'// Before block'</em>);
Writeln;
<b>begin</b>
Writeln(<em>'// Before first inline var...'</em>);
<b>var</b> I2 := TTalking.Create(<em>'Two'</em>) <b>as</b> ITalking; <i>// the other way: type inference</i>
I2.Talk;
<b>var</b> I3: ITalking := TTalking.Create(<em>'Three'</em>);
I3.Talk;
Writeln(<em>'// Do something useful here'</em>);
<b>end</b>;
Writeln;
Writeln(<em>'// After block'</em>);
<b>var</b> I4: ITalking := TTalking.Create(<em>'Four'</em>);
Writeln(<em>'// After declaration of Four'</em>);
<b>end</b>;
</pre>
<p>And the output is:</p>
<pre style="background-color: #000000; color: #FFFFFF">
Creating One
// Before block
// Before first inline var...
Creating Two
Hi, Two talking here!
Creating Three
Hi, Three talking here!
// Do something useful here
Destroying Three
Destroying Two
// After block
Creating Four
// After declaration of Four
Destroying Four
Destroying One
</pre>
<p>As you can see, the two interfaces declared and initialized <em>inside</em> the inner block are destroyed <em>at the end of the same block</em>. The interfaces declared and initialized in the outer block are destroyed at the end of the function.</p>
<p>This creates some interesting opportunities, e.g. for <a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization">RAII</a> using interfaces, or other auto-finalized structures. RAII doesn't have to be used for smart pointers. It can also be used for many other things, like locks, mutexes, temporary changes of cursors, etc. i.e. anything that is changed temporarily and restored at the end of a certain period. Just declare the RAII object inside the block and the change will be restored at the end of it. Just pass it an anonymous function to tell it what it must do at the end of the block (or in case of an exception).</p>
<p>But more about this later. FWIW, I also like the type inference, or that it can be used for <code>for</code>-loops.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com2tag:blogger.com,1999:blog-4471683011000431353.post-23966714759001139082018-10-05T14:08:00.000+02:002018-10-05T14:08:09.584+02:00Why I like Stack Exchange<p>Because you can get extremely interesting answers, like the excellent answer to the question <a href = "https://physics.stackexchange.com/questions/432137/what-is-chirped-pulse-amplification-and-why-is-it-important-enough-to-warrant-a">"What is Chirped Pulse Amplification, and why is it important enough to warrant a Nobel Prize?"</a> on Physics Stack Exchange:<p>
<p><em>The 2018 Nobel Prize in Physics <a href="https://www.nobelprize.org/prizes/physics/2018/summary/">has just been announced</a>, with half going to Arthur Ashkin for his work on optical tweezers and half going to Gérard Mourou and Donna Strickland for developing a technique called "Chirped Pulse Amplification". While normally <a href="https://en.wikipedia.org/wiki/Chirped_pulse_amplification">the Wikipedia page</a> is a reasonable place to turn to, in this case it's pretty flat and not particularly informative. So:</em></p>
<ul>
<li><em>What is Chirped Pulse Amplification? What is the core of the method that really makes it tick?</em></li>
<li><em>What pre-existing problems did its introduction solve?</em></li>
<li><em>What technologies does it enable, and what research fields have become possible because of it?</em></li>
</ul>
<p>I am not a physicist and just know the usual school physics, but have no problem understanding the answer. Excellent!</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com2tag:blogger.com,1999:blog-4471683011000431353.post-78617948325022403242018-10-01T21:41:00.000+02:002018-10-30T20:02:59.427+01:00The current state of generics in Delphi<p>To avoid duplication of generated code, the compiler builders of Embarcadero have done a nice
job. They introduced new instrinsics like <code>IsManagedType</code>, <code>GetTypeKind</code> and
<code>IsConstantType</code> (see <a href="https://stackoverflow.com/a/30417597/95954">this Stackoverflow answer</a>),
so they could make a function like the following generate a call to the exact function for the parametric type directly. This means that
the code below "runs" completely inside the compiler, even the code in the called <code>InternalAddMRef</code> and
similar dispatching routines.</p>
<pre><b>function</b> TList<T>.Add(<b>const</b> Value: T): Integer;
<b>begin
if</b> IsManagedType(T) then
<b>begin
if</b> (SizeOf(T) = SizeOf(Pointer)) <b>and</b> (GetTypeKind(T) <> tkRecord) <b>then</b>
Result := FListHelper.InternalAddMRef(Value, GetTypeKind(T))
<b>else if</b> GetTypeKind(T) = TTypeKind.tkVariant <b>then</b>
Result := FListHelper.InternalAddVariant(Value)
<b>else</b>
Result := FListHelper.InternalAddManaged(Value);
<b>end else
case</b> SizeOf(T) <b>of</b>
1: Result := FListHelper.InternalAdd1(Value);
2: Result := FListHelper.InternalAdd2(Value);
4: Result := FListHelper.InternalAdd4(Value);
8: Result := FListHelper.InternalAdd8(Value);
<b>else</b>
Result := FListHelper.InternalAddN(Value);
<b>end</b>;
<b>end</b>;</pre>
<p>That, in its turn, means that if you code something like:</p>
<pre><b>var</b>
List: TList<<b>string</b>>;
<b>begin</b>
List := TList<<b>string</b>>.Create;
List.Add(<i>'Hello'</i>);
</pre>
<p>then</p>
<pre>List.Add(<i>'Hello'</i>);</pre>
<p>is in fact directly compiled as</p>
<pre>List.FListHelper.DoAddString(<i>'Hello'</i>);</pre>
<p>i.e. <code>TList.Add</code> does not have any runtime code at all, the result of "calling" it (see above) is the generation of a direct
call to the <code>DoAddString</code> function. That is a simple method, not generic,
not virtual or dynamic, like all the other methods of TListHelper, so the unused
functions can be eliminated by the linker. This also means there is hardly any duplication
of <em>generated</em> code anymore, i.e. if another part of the same executable also uses
<code>TList<string>.Add</code> it will use the same function.</p>
<h2>No code duplication?</h2>
<p>Well, this means that if the class is coded like above, there is no unnecessary duplication of <em>generated</em> code anymore.
That is cool and can probably reduce the expected bloat caused by using generics.<p>
<p>But it also means that it greatly reduces one of the advantages associated with generics: <strong>no unnecessary duplication of
source code</strong>. You write a routine once, and only the type it works on is parametrized. The compiler takes care of
generating code for each used routine and parametric type.</p>
<p>But then you still get the dreaded bloat. So you either duplicate a lot of source code (take a look at the code of
<code>TListHelper</code> in <code>System.Generics.Collections</code> to see what I mean; for example, the functions
<code>DoAddWideString</code>, <code>DoAddDynArray</code>, <code>DoAddInterface</code> and <code>DoAddString</code>
contain <em>exactly</em> the same code, except for the lines where <code>FItems^</code> is cast each to a different pointer type),
which is almost as much work as writing a separate <code>TList</code> for each type, or you use the naïve approach, writing code
only once, as generics should actually be used. But then you could get bloat again, i.e. it is well possible that the same routine
gets generated multiple times, in different units of the same executable.</p>
<h2>What to do?</h2>
<p>There is not much we can do, except to <strong>emphatically ask Embarcadero to put the kind of logic that was implemented in <code>TList<T></code> and other generic
classes to avoid duplication of <em>generated</em> code, in the compiler and linker</strong>, so we don't have to write huge helper classes nor get the bloat.</p>
<p>In the meantime, you can do what Embarcadero did: if your class is used a lot for many different types, do a lot of "copy and paste generics".
Otherwise, if you only have to deal with a few types and in a few places, simply use the naïve approach. Or you use a hybrid approach, using the
intrinsics mentioned above and implementing the most used helper functions for the types you need most.</p>
<p>Let's hope they get a lot of requests and implement these things in the compiler and linker, like other languages with generics, e.g. C# or C++, do.</p>
<p><em>Rudy Velthuis</em></p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-67938831597014501522018-09-14T21:38:00.000+02:002019-01-09T17:43:08.668+01:00Making Delphi operator overloads compatible with C++Builder<h2>Delphi operator overloads</h2>
<p>A few days ago, I made a simple test program to test my <a href="https://github.com/rvelthuis/DelphiBigNumbers">BigIntegers</a> in C++Builder. The important part looked like this:</p>
<pre><i style="font-style: normal">#include "Velthuis.BigIntegers.hpp"</i>
<b>int</b> _tmain(<b>int</b> argc, _TCHAR* argv[])
{
BigInteger a = 17;
BigInteger b = <i>"123"</i>;
BigInteger c = a + b;
</pre>
<p>But that did not compile. I got the following error message for the line that did the addition:</p>
<blockquote>[bcc32c Error] File13.cpp(16): invalid operands to binary expression ('Velthuis::Bigintegers::BigInteger' and 'Velthuis::Bigintegers::BigInteger')</blockquote>
<p>Now, <em>BigIntegers</em>, as I defined them, have overloads for many arithmetic and relational operators. A sample:</p>
<pre> <b>class operator</b> Add(<b>const</b> Left, Right: BigInteger): BigInteger;
<b>class operator</b> Subtract(<b>const</b> Left, Right: BigInteger): BigInteger;
<b>class operator</b> Multiply(<b>const</b> Left, Right: BigInteger): BigInteger;
</pre>
<p>But taking a look in the (Delphi-)generated <em>Velthuis.BigInteger.hpp</em> file, I saw that these are
declared as simple static functions with an <code>_op_</code> prefix:</p>
<pre><b>static</b> BigInteger <b>__fastcall</b> _op_Addition(<b>const</b> BigInteger &Left,
<b>const</b> BigInteger &Right);
<b>static</b> BigInteger <b>__fastcall</b> _op_Subtraction(<b>const</b> BigInteger &Left,
<b>const</b> BigInteger &Right);
<b>static</b> BigInteger <b>__fastcall</b> _op_Multiply(<b>const</b> BigInteger &Left,
<b>const</b> BigInteger &Right);
</pre>
<p><span style="font-size: small"><em>Lines wrapped to make them more readable in this blog</em></span></p>
<p>So, to use them, you have to call them explicitly:</p>
<pre>
BigInteger c = BigInteger::_op_Addition(a, b);
</pre>
<p>That is ugly, and unusual for someone used to C++'s operator overloading. It makes using <em>BigIntegers</em> pretty inconvenient. OK, I defined static backup functions for the arithmetic overloads, so in the case of <em>BigIntegers</em>, you can just as well use a more or less Java-style method call:<p>
<pre>
BigInteger c = BigInteger::Add(a, b);
</pre>
<h2>C++ operator overloads</h2>
<p>I wanted my operator overloads to be usable as in the first code sample. I read up a bit on C++ operator overloading, and came up with the following solution:</p>
<pre><b>inline</b> BigInteger <b>operator</b> +(<b>const</b> BigInteger& left, <b>const</b> BigInteger& right)
{ <b>return</b> BigInteger::Add(left, right); }</pre>
<p>I added that line to the C++ file before the <code>main</code> function, and all of a sudden it compiled and even produced the right result. So I wrote a file called <em>Velthuis.BigIntegers.operators.hpp</em>, with lines similar to the above for all supported operator overloads and included that too:</p>
<pre><i style="font-style: normal">#include "Velthuis.BigIntegers.hpp"
#include "Velthuis.BigIntegers.operators.hpp"</i></pre>
<p>Ok, that worked. But I didn't find that solution very satisfactory. To use <em>BigIntegers</em> with overloaded operators, you had to include an additional header file. And I could not just include that file in the <em>Velthuis.BigIntegers.hpp</em> file, because that is generated by the Delphi compiler, and any re-generation would overwrite any edits made to it. So what to do?</p>
<h2>Including new header in generated header</h2>
<p>But then I remembered that there is something like <code>{$HPPEMIT}</code> in Delphi. That allows you to add extra lines of C++ code to a generated <em>.hpp</em> file. So I added:</p>
<pre><i style="font-style: normal">{$HPPEMIT '#include "Velthuis.BigIntegers.operators.hpp"'}</i></pre>
<p><strong>But that did not compile at all!</strong> I looked at the generated <em>.hpp</em> file and saw that the line was added somewhere near the top, well before the declaration of <em>BigInteger</em>. But it had to be included near the bottom of the generated hpp. Fortunately, the online help shows that nowadays (according to Remy Lebeau, even since Delphi 2009 or 2010), you can add an <code>END</code> attribute to the directive:</p>
<pre><i style="font-style: normal">{$HPPEMIT END '#include "Velthuis.BigIntegers.operators.hpp"'}</i></pre>
<p>And now it was added somewhere near the bottom of the header, well after the declaration of <em>BigInteger</em>. Success! Now the code sample at the top of this post compiled and worked as expected.</p>
<h2>Conclusion</h2>
<p>To recap: To make Delphi-defined operator overloads usable in C++, you will have to</p>
<ul>
<li>write C++ operator overload wrappers for them.</li>
<li>You can pack those in a header of its own</li>
<li>and then include that header in the generated header for your Delphi file using <code>{$HPPEMIT END '#include "NameOfYourHeader"'}</code>.</li>
</ul>
<p>I added these changes to my <a href="https://github.com/rvelthuis/DelphiBigNumbers">GitHub repository DelphiBigNumbers</a>.</p>
<em>Rudy Velthuis</em>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com3tag:blogger.com,1999:blog-4471683011000431353.post-46514040105502467852018-03-09T18:21:00.000+01:002018-03-11T00:36:22.019+01:00Converting line endings<h2>eolconv</h2>
<p style="background-color: #e8ffe8; color: #040; border: 1px solid #c0e0c0; border-radius: 5px; padding: 10px;"><em>An up-to-date version of this and other files can be found in my <strong>CommandLineTools</strong> project on <a href="https://github.com/rvelthuis/CommandLineTools">GitHub</a>.</em></p>
<p>On <a href="https://stackoverflow.com/questions/tagged/delphi">Stack Overflow</a> and in the <a href="https://forums.embarcadero.com/index.jspa">Embarcadero forums</a> I regularly see people ask how to convert a file with Unix line endings to Windows line endings, or vice versa. The usual advice is to load the file into <a href="https://notepad-plus-plus.org/">Notepad++</a> and to save it with the desired line ending format.</p>
<p>But Delphi can do this too, either using <code>AdjustLineBreaks</code> or using a <code>TStringList</code>. That is why I wrote this simple command line tool. The actual conversion is extremely simple:</p>
<ul>
<li><del>Load the file into a <code>TStringList</code>.</del></li>
<li><del>Set the <code>LineBreak</code> property of the string list, depending on the desired output format (Windows or Unix).</del></li>
<li>Convert the file depending on the encoding: 8 bit, 16 bit little endian or 16 bit big endian.</li>
<li>Rename the old file to a name with a unique extension.</li>
<li>Rename the new file to the name of the old file.</li>
<li><del>Save the contents of the <code>TStringList</code> back to the file.</del></li>
</ul>
<p><del><em>Most of the code is there to handle command line parameters.</em></del></p>
<h3>Update</h3>
<p><em>The TStringList way is simple to write, but is not only pretty slow and — if the file is large — can also require a lot of memory. The new way uses a buffer of up to 2MB to load blocks of the file and convert on the fly. This turned out to be a lot faster for large files.</em></p>
<h2>Synopsis</h2>
<pre>EOLCONV [options ...] Name[s]</pre>
<p>Multiple file names can be specified. <em>EOLConv</em> does not understand wildcards (yet), but for instance on the Windows command line, you can do something like:</p>
<pre>for %f in (*.txt) do eolconv %f -U</pre>
<p>That will convert all files with the extension <code>.txt</code> in the current directory to the Unix format.</p>
<p>Each original file will be preserved by renaming it, adding a unique <code>.~1</code>, <code>.~2</code>, etc. extension to the original file name. <em>EOLConv</em> will try to add extensions up to <code>.~200</code>, and if the file name with that extension exists too, <em>EOLConv</em> will give up and the original file will remain as it was.</p>
<h2>Options</h2>
<p>On Windows, all options start with either a <code>/</code> or a <code>−</code>. On other platforms, they start with a <code>−</code>.</p>
<p>Options are case insensitive.</p>
<p>If no options are specified, the files will be converted to the default line ending format for the platform. To set the line ending format to a specific style, use:</p>
<ul style="list-style: none;">
<li><code>-W</code> to set the line endings to Windows format (CR+LF)<sup>*</sup></li>
<li><code>-U</code> to set the line endings to Unix format (LF)<sup>*</sup></li>
</ul>
<p style="font-size: small; border-top: 1px solid #AAA; border-bottom: 1px solid #AAA;"><em><sup>*</sup> CR stands for Carriage Return (<code>#13</code> in Delphi), LF stands for Line Feed (<code>#10</code> in Delphi)</em>.</p>
<p>To get help, either start <em>eolconv</em> without any parameters, or specify <code>-H</code> or <code>-?</code>.</p>
<h2>Finally</h2>
<p><em>EOLConv is freeware. All rights are reserved. Its code is provided as is, expressly without a warranty of any kind. You use it at your own risk.</em></p>
<p>I hope this code is useful to you. If you use some of it, please credit me. If you modify or improve <em>EOLConv</em>, please send me the modifications.</p>
<p>I may improve or enhance <em>EOLConv</em> myself, and I will try to post changes here. But this is not a promise. Please don’t request features.</p>
<p><em>Rudy Velthuis</em></p>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-28975481304126279982018-03-04T20:51:00.002+01:002018-03-05T18:23:04.725+01:00AutoSuffix<p>I guess everyone who had to maintain one package for several different versions of Delphi had wished this was
possible to do with a single package source. The alternative is to have different set of <var>.dpk</var> and <var>.dproj</var> files,
each with a different name or suffix, for each version you want to cover.</p>
<p>Some, including me, devised a "clever" include file that set a different <code>{$LIBSUFFIX }</code> for each
version. So did I, but every simple change to the package would remove the
<code>{$INCLUDE 'LibSuffixes.inc'}</code> I put in the <var>.dpk</var> file and replace it with something like <code>{$LIBSUFFIX '230'}</code>
if 230 was the suffix found in the <var>.dproj</var> file.</p>
<p>If you are very careful not to modifiy the package, and the include file is not removed, this compiles as intended, i.e. a
file <var>MyPackage.dpk</var> compiles as <var>MyPackage250.bpl</var>, but if you try to install that way the IDE is not
aware of the changed suffix, so it complains that it could not install <var>MyPackage.bpl</var>.</p>
<p>Note: <em>The <code>{$LIBSUFFIX}</code> directive works for DLLs too, but there is no entry in the </em>Project → Options... → Description<em> page (there is not even a </em>Description<em> page).
The previously mentioned "clever" includes work very well for DLLs
(and so for DLL-based experts too). The IDE does not meddle with the contents of a <var>.dpr</var> file for a <code>library</code>.</em></p>
<p>This problem has been discussed many times on forums and in communities. On <var>Stack Overflow</var>, someone called
<var>LaKraven</var> set out to create an IDE expert (<var>AutoSuffix</var>) to solve this problem. But I can't find this expert anymore.
All the links I found to it are dead.</p>
<h2>The <em>New</em> AutoSuffix Expert</h2>
<p>So I wrote a simple expert myself and called it <var>AutoSuffix</var> too.</p>
<p>If the current project is a package, it adds a menu item to the context menu of the Project Manager
with the title <em>Add Version Suffix</em>, under the <em>Rename</em> menu item. If you click it,
it sets the suffix for the package to a number that matches the suffixes used for the
version of the compiler, i.e. for Delphi 10.2 Tokyo, it sets it to <var>250</var>, for 10.1 Berlin
to <var>240</var>, for XE3 to <var>170</var>, etc.</p>
<p><em>I could have made this an expert that sets the suffix automatically, but I wanted to leave the
user (myself too) a choice, so it must be done manually, using the context menu.</em></p>
<h2>Tested</h2>
<p>I only tested this in Delphi XE3, Delphi 10 Seattle, 10.1 Berlin and 10.2 Tokyo, but it probably works in
versions inbetween as well. I will update this as soon as I have tested it more.</p>
<h2>Installation</h2>
<p>Get all the files from <a href="https://github.com/rvelthuis/AutoSuffix">GitHub</a> (either clone the repository
or download the files as <var>zip</var>) and put them in a single directory. Open the package <var>AutoSuffix.dproj</var> in
your IDE, select the project in the Project Manager and click the <var>Install</var> menu item from the context menu.
If all is well, this installs the expert and adds one menu item to the context menu of the Project Manager:
<var>Add Version Suffix</var>, under the <var>Rename</var> item. This menu item only appears if the project is a package.
<p><em>Rudy Velthuis</em></p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com7tag:blogger.com,1999:blog-4471683011000431353.post-36409639318789426382018-02-01T19:02:00.000+01:002018-02-01T19:08:37.038+01:00Optimizing ARC the hard way?<h3>The problem</h3>
<p>In a <a href="https://dalijap.blogspot.de/2018/01/optimizing-arc-hard-way.html">recent blog post</a>, Dalija Prasnikar talks about how hard it would be to optimize ARC code,
because most ARC object references will be passed by value, but not as <code>const</code>. Passing as <code>const</code> would
eliminate the need for an implicit <code>__ObjAddRef()</code> call each time the object is passed (and an <code>__ObjRelease()</code> call when the routine
with the parameter ends).</p>
<p>OK, ARC (automatic reference counting) has been used for many types already, most of
all strings, dynamic arrays and interfaces. Code passing strings and dynarrays is generally
optimized already, by specifying such parameters as <code>const</code>. There are probably only a few exceptions.
It is also customary to do it with interfaces, and the few exceptions probably don't make a big
difference in performance. But it is far from customary to do this for objects. Until ARC, it
didn't matter if you passed an object as <code>const</code> or not. But these days, in ARC, it can make a big
difference. And objects are passed around a lot, e.g. the <code>Sender</code> parameter of events, etc.</p>
<p>Note that most runtime and FMX code doesn't use <code>const</code> to pass objects either, nor do any of the
third parties. Dalija notes that it is not hard to add <code>const</code> to each object parameter, but that it would
break huge amounts of code, not only Embarcadero's, but everyone's.</p>
<h3>Switch?</h3>
<p>I read that and have been thinking about it a little. I first thought of introducing a switch
(sound familiar?) in the new ARC compilers, that would make <code>const</code> optional and reduce compiler
complaints about interface changes, to make this transition easier. But that would still
require a huge amount of code changes, even if it could perhaps be done at a slower pace.</p>
<h3>Const by default?</h3>
<p>But then I thought of something else. If an object is passed as call-by-value, to a method or
function, inside that method or function, you very seldom change the reference by assigning a
<strong>new</strong> object to it. In other words, inside such a method or function, you hardly ever
do something like:</p>
<pre>
ObjectParam.Free; <i>// necessary in non-ARC, optional in ARC</i>
ObjectParam := TSomeObject.Create;
</pre>
<p>Yes, you often change the state of the object by setting properties or by calling methods, but that can
be done on a <code>const</code> reference as well. <code>Const</code> means you can't change the reference,
not that you can't change the state of the object it refers to.</p>
<p>For almost all practical purposes, such objects passed can be treated <em>as if they were passed as
<code>const</code> already</em>. So it would perhaps make sense, in a new version of the ARC compilers, to treat
<em>every</em> pass-by-value as <code>const</code>. This would make the code compatible with
the non-ARC compilers, while still avoiding a truckload of reference counting calls. This would
probably optimize ARC code quite a lot. Of course code already using <code>const</code> would be
compatible too. And it would not apply to code using <code>var</code> or <code>out</code>, only to plain
pass-by-value object reference parameters.</p>
<p>And the very few methods that do actually re-use a parameter like above should simply be rewritten
to use a (new) local variable for the new object. I doubt there is lot of code that does this anyway, so
this change would not break a lot of code at all.</p>
<p>So making all passed-by-value objects <code>const</code> by default would probably break very little code, and
optimize a lot of ARC code. It would not affect non-ARC code.</p>
<p>As for the old compilers: they would remain non-optimized, but their code would not have to be
changed. A simple recompile (and the occasional change) would suffice.</p>
<p>I'd love to hear about your thoughts.</p>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com8tag:blogger.com,1999:blog-4471683011000431353.post-59110659883232814032018-01-22T13:51:00.001+01:002018-10-01T22:37:54.991+02:00Accessing private methods of another class<p>In versions of Delphi before 10.1 Berlin, it was possible to access private members and private methods of a
class simply by defining a class helper for it and accessing these private items in its methods.</p>
<p>But that it was so easy to access private members undermined the basic OO principles of
information hiding and encapsulation. That is why this loophole (which could be considered a bug)
was closed in Delphi 10.1 Berlin. But there was a lot of howling about this, because it was so easy
and so convenient to have access to everything, even to other classes' "private parts".</p>
<p>There has been a lot of discussing going on about this. I will not repeat the arguments made
there, but will state that I agree with the closing of the loophole. Accessing private members or
methods is a hack, and a hack should never be easy. This hack was far too easy. Instead of using the
hack, people should rather have tried to find other ways to achieve their goals.</p>
<p>But there is one argument of the pro-helper people that actually made sense: sometimes a class is
not designed well, and you <em>must</em> resort to hacks.</p>
<h3>Three hacks</h3>
<p>They have all been mentioned before, in several blogs and StackOverflow answers, but I want to
recap them here, in one post. All of these still require helper classes, as only there, you can
still access private methods or members.</p>
<h3>Accessing private methods</h3>
<p>Say we have a class, let's call it <code>THasPrivateMethods</code>, that has at least one private
method, let's say <code>procedure PrivateMethod</code>, that you want to call. The following three
ways to call the private method have all been verified in Delphi 10.2.2 Tokyo. They should also
work in previous versions.</p>
<h4>Using assembler</h4>
<p>The first way to get at private methods is to define a helper class with a new method. Here, I'll
call the helper <code>THelper</code> and the first method <code>CallingPrivateMethodUsingAsm</code>.
This method must be an assembler method:</p>
<pre>
<b>type</b>
THelper = <b>class</b> helper <b>for</b> THasPrivateMethods
<b>public</b>
<b>procedure</b> CallingPrivateMethodUsingAsm;
<b>end</b>;
</pre>
<p>The implementation is extremely simple:</p>
<pre>
<span style="color: #008000;">{$STACKFRAMES OFF}</span>
<b>procedure</b> THelper.CallingPrivateMethodUsingAsm;
<b>asm</b>
<span style="color: #008080;"> JMP THasPrivateMethods.PrivateMethod</span>
<b>end</b>;
</pre>
<p>In other words, in assembler, helper methods can still access private methods.</p>
<h4>Using a method pointer</h4>
<p>For those who are not very good with assembler, there is another, more tedious way, using a
method pointer:</p>
<pre>
<b>procedure</b> CallingPrivateMethodUsingTMethod; <b>inline</b>;
</pre>
<p>The implementation takes the address of the private method (which can apparently still be
queried), puts it in a method pointer and then calls the method pointer:</p>
<pre>
<b>type</b>
TPrivateMethod = <b>procedure of object</b>;
...
<b>procedure</b> THelper.CallingPrivateMethodUsingTMethod;
<b>var</b>
M: TMethod;
<b>begin</b>
M.Code := @THasPrivateMethods.PrivateMethod;
M.Data := Self;
TPrivateMethod(M);
<b>end</b>;
</pre>
<h4>Using with</h4>
<p>Inside a method of a class helper, you can't call a private method directly anymore, but you can
use a simple trick (probably forgotten when they closed the loophole), using "<code>with Self
do</code>". I am no fan of "<code>with</code>", but in this special case, it works as expected:</p>
<pre>
<b>procedure</b> THelper.CallingPrivateMethodUsingWith;
<b>begin</b>
<b>with</b> Self <b>do</b> PrivateMethod;
<b>end</b>;
</pre>
<p>Yes, it is that easy. But you must use "<code>with Self do</code>" to call the private method. Now,
if you inline this method, there is <em>absolutely no overhead</em>. It will work as if you had
called the private method in your own routine:</p>
<pre>
<b>procedure</b> NeedsAccessToPrivateMethod;
<b>var</b>
H: THasPrivateMethods;
<b>begin</b>
H := THasPrivateMethods.Create;
<b>try</b>
// ...
H.CallingPrivateMethodUsingWith;
// ...
<b>finally</b>
H.Free;
<b>end</b>;
<b>end</b>;
</pre>
<p>Again, if <code>CallingPrivateMethodUsingWith</code> is inlined, the resulting code is the same
as if you had written:</p>
<pre>
<b>try</b>
// ...
H.PrivateMethod;
// ...
<b>finally</b>
</pre>
<p>If you can read assembler, you can verify this in the CPU view of the IDE.</p>
<p>I will discuss accessing private fields in a later post.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com11tag:blogger.com,1999:blog-4471683011000431353.post-86746070056799524262018-01-15T21:48:00.000+01:002018-03-08T18:09:09.882+01:00Strings too slow outside WIN32?<p>In a recent debate I had it was said that strings in the <em>Win64</em>
runtime are too slow to be useful. That is, in my opinion, a gross
exaggeration. It is true that the <em>Win32</em> runtime library (RTL) has
benefited a lot from the work of the <em>FastCode</em> project, usually with
routines in extremely clever assembler. For all other platforms, often the
routines are in plain <em>Object Pascal</em>, so no assembler is being used.
Also, far fewer routines have been replaced by clever implementations.</p>
<p>One very obvious example of this is the <code>Pos</code> function, which
searches if a certain string (I call that the <code>Needle</code>) can be found
in a larger one (the <code>Haystack</code>). The <em>Win32</em> implementation
is in highly optimized assembler, written by <em>Aleksandr Sharahov</em> from
the <em>FastCode</em> project, and licensed by CodeGear. The <em>Win64</em>
implementation is in plain Pascal (<code>PUREPASCAL</code>). But the
implementation for <code>UnicodeString</code> is not the same, or even similar,
to the implementation for <code>AnsiString</code>!</p>
<p>The implementation for <code>UnicodeString</code> is slower than the same
routine for <em>Win32</em>. On my system a search in <em>Win64</em> takes
approx. 1.8 × the time it needs in <em>Win32</em>. On <em>Win32</em>,
<code>Pos</code> for <code>AnsiString</code> is about as fast (or sometimes
even slightly faster than) <code>Pos</code> for <code>UnicodeString</code>. But
on <em>Win64</em>, <code>Pos</code> for <code>AnsiString</code> takes 2 ×
the time <code>Pos</code> for <code>UnicodeString</code> needs!</p>
<p>If you look at the sources in <code>System.pas</code>, you'll see that the
<em>Unicode</em> version is slightly better optimized (searching for the first
<code>Char</code> in the <code>Needle</code> first, and only checking the rest
if a match was found).</p>
<p>For fun, I took the code for the <code>UnicodeString</code> implementation and converted
it to work for <code>AnsiString</code>. It was slightly faster than <code>System.Pos</code>
for <code>UnicodeString</code>, instead of 2 times as slow. I wonder why, in <code>System.pas</code>, the <code>AnsiString</code>
implementation does not simply use the same code as that for <code>UnicodeString</code>,
like I did. If I were a suspicious person, I would think it was done on purpose,
to deprecate <code>AnsiString</code> by making it less usable.</p>
<p>But even that can be improved upon. I wrote three implementations of my own
routine, one for <code>AnsiString</code>, one for <code>UnicodeString</code> and one for <code>TBytes</code> (many
people have complained that <code>TBytes</code> lacks something like <code>Pos</code> and
that was the reason they maintained the incredibly bad habit of <em>using
strings to store binary data</em> — <shudder> — I wanted to take away that
silly argument).</p>
<h3>Code</h3>
<p>Here is the code for my <code>RVPosExA</code> function (for what it's worth: these days, there is no difference
between <code>PosEx</code> and <code>Pos</code> anymore: both have the exact same functionality and signature):</p>
<pre>
<b>function</b> RVPosExA(<b>const</b> Needle, Haystack: AnsiString;
Offset: Integer = 1): Integer;
<b>type</b>
PUInt32 = ^UInt32;
PUInt16 = ^UInt16;
<i>{$IFNDEF CPU32BITS}</i>
<b>var</b>
LNeedleTip: UInt32;
PNeedle: PAnsiChar;
PHaystack, PEnd: PAnsiChar;
LLenNeedle: Integer;
LCmpMemOffset: Integer;
<i>{$ENDIF}</i>
<b>begin</b>
<i>{$IFDEF CPU32BITS}</i>
<i>// FastCode (asm) implementation.</i>
Result := System.Pos(Needle, Haystack, Offset);
<i>{$ELSE}</i>
<b>if</b> Offset - 1 + Length(Needle) > Length(Haystack) <b>then</b>
Exit(0);
Result := 0;
PHaystack := PAnsiChar(Haystack) + Offset - 1;
PEnd := PHaystack + Length(Haystack) - Length(Needle) + 1;
<b>case</b> Length(Needle) <b>of</b>
0: Exit(0);
1:
<b>begin</b>
LNeedleTip := PByte(Needle)^;
<b>while</b> PHaystack < PEnd <b>do
if</b> PByte(PHaystack)^ = LNeedleTip <b>then</b>
Exit(PHaystack - PAnsiChar(Haystack) + 1)
<b>else</b>
Inc(PHaystack);
Exit(0);
<b>end</b>;
2:
<b>begin</b>
LNeedleTip := PUInt16(Needle)^;
<b>while</b> PHaystack < PEnd <b>do
if</b> PUInt16(Haystack)^ = LNeedleTip <b>then</b>
Exit(PHayStack - PAnsiChar(Haystack) + 1)
<b>else</b>
Inc(PHaystack);
Exit(0);
<b>end</b>;
3:
<b>begin</b>
LNeedleTip := PUInt32(Needle)^; <i>// if Needle is length 3, then top byte
// is the #0 terminator</i>
<b>while</b> PHaystack < PEnd <b>do</b>
<b>if</b> ((PUInt32(Haystack)^ <b>xor</b> LNeedleTip) and $FFFFFF) = 0 <b>then</b>
Exit(PHaystack - PAnsiChar(Haystack) + 1)
<b>else</b>
Inc(PHaystack);
Exit(0);
<b>end</b>;
4:
<b>begin</b>
LNeedleTip := PUInt32(Needle)^;
<b>while</b> PHaystack < PEnd <b>do</b>
<b>if</b> PUInt32(Haystack)^ = LNeedleTip <b>then</b>
Exit(PHaystack - PAnsiChar(Haystack) + 1)
<b>else</b>
Inc(PHaystack);
Exit(0);
<b>end</b>;
<b>else
begin</b>
LCmpMemOffset := SizeOf(UInt32) <b>div</b> SizeOf(AnsiChar);
PNeedle := PAnsiChar(Needle) + LCmpMemOffset;
LLenNeedle := Length(Needle) - LCmpMemOffset;
LNeedleTip := PUInt32(Needle)^;
<b>while</b> PHaystack < PEnd <b>do</b>
<b>if</b> (PUInt32(PHaystack)^ = LNeedleTip) <b>and</b>
CompareMem(PHaystack + LCmpMemOffset, PNeedle, LLenNeedle) <b>then</b>
Exit(PHaystack - PAnsiChar(Haystack) + 1)
<b>else</b>
Inc(PHaystack);
<b>end</b>;
<b>end</b>;
<i>{$ENDIF}</i>
<b>end</b>;
</pre>
<p>As you can see, under <em>Win32</em>, it simply jumps to
<code>System.Pos</code>, as that is the fastest anyway. But on all other
platforms, it searches the <code>Haystack</code> 4-byte-wise (if the
<code>Needle</code> is larger than 4 elements), and if it found something, then
it searches the rest using <code>CompareMem</code>.
<h3>Timing</h3>
<p>Here is a slightly reformatted output of a test program (I put the <em>WIN32</em> and the <em>WIN64</em> columns beside each other, to save space):</p>
<pre>
Different versions of Pos(Needle, Haystack: <sometype>; Offset: Integer): Integer
where <sometype> is UnicodeString, AnsiString or TBytes
Testing with Haystack lengths of 50, 200, 3000, 4000 and 300000
and Needle lengths of 1, 3, 8 and 20
5 * 4 * 2000 = 40000 loops
WIN64 WIN32
UnicodeString UnicodeString
------------- -------------
System.Pos: 2428 ms System.Pos: 1051 ms
StrUtils.PosEx: 2258 ms StrUtils.PosEx: 1070 ms
RVPosExU: 1071 ms RVPosExU: 1050 ms
AnsiString AnsiString
---------- ----------
System.Pos: 4956 ms System.Pos: 1046 ms
AnsiStrings.PosEx: 4959 ms AnsiStrings.PosEx: 1051 ms
OrgPosA: 5129 ms OrgPosA: 5712 ms
PosUModForA: 1958 ms PosUModForA: 3744 ms
RVPosExA: 1322 ms RVPosExA: 1086 ms
TBytes TBytes
------ ------
RVPosEXB: 998 ms RVPosEXB: 2754 ms
Haystack: random string of 500000000 ASCII characters or bytes
Needle: last 10 characters of Haystack = 'WRDURJVDFA'
WIN64 WIN32
UnicodeString UnicodeString
------------- -------------
System.Pos: 847 ms System.Pos: 421 ms
Strutils.PosEx: 827 ms Strutils.PosEx: 414 ms
RVPosExU: 421 ms RVPosExU: 438 ms
AnsiString AnsiString
---------- ----------
System.Pos: 1735 ms System.Pos: 428 ms
AnsiStrings.PosEx: 1831 ms AnsiStrings.PosEx: 428 ms
OrgPosA: 1749 ms OrgPosA: 2687 ms
PosUModForA: 708 ms PosUModForA: 1525 ms
RVPosExA: 368 ms RVPosExA: 423 ms
RvPosExA(,,Offset): 200 ms RvPosExA(,,Offset): 220 ms
TBytes TBytes
------ ------
RVPosExB(TBytes): 385 ms RVPosExB(TBytes): 1095 ms
</pre>
<p>The routines <code>RVPosExA</code>, <code>RVPosExU</code> and <code>RVPosExB</code> are my implementations for <code>AnsiString</code>, <code>UnicodeString</code> and <code>TBytes</code> respectively. <code>OrgPosA</code> is the original code for <code>Pos</code> for <code>AnsiString</code>, while <code>PosUModForA</code> is the original <em>PUREPASCAL</em> code for <code>Pos</code> for <code>UnicodeString</code>, modified for <code>AnsiString</code>.</p>
<p>As you can see, the <code>PosUModForA</code> routine is almost twice as fast as the rather braindead <code>OrgPosA</code>, and in <em>WIN32</em>, the <code>RVPosEx<A/U/B></code> implementations are faster than the others.</p>
<p>I didn't check, but it is well possible that one of the plain Pascal versions of the <em>FastCode</em> project is faster. But for me, this implementation is a start and proof, that with a few simple optimizations string routines could be made faster. Perhaps, one day, Embarcadero will adopt more of the plain Pascal code from the FastCode project.</p>
<p>The code for the routines and the program that produces the output above can be <a href="http://rvelthuis.de/zips/poscomparisons.zip">downloaded from my website</a>.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com4tag:blogger.com,1999:blog-4471683011000431353.post-60800806476326356582017-09-01T20:16:00.000+02:002017-09-01T22:04:14.965+02:00Smart pointers<h2>Introduction</h2>
<p>Today, I had a <a href="https://stackoverflow.com/questions/45983184/delphi-avoid-try-finally-block">discussion on StackOverflow</a> (I hope no one deleted it yet) on the usefulness of smart pointers instead of <code>try</code>...<code>finally</code>.</p>
<p>My arguments are as follows:
<p> 1. <code>try</code>...<code>finally</code> decreases the readability of a function, especially if they are nested, e.g. when you instantiate a <code>TStream</code> and then a <code>TStringList</code>. Then you would need two nested <code>try</code>...<code>finally</code> constructs, thoroughly decreasing readability.</p>
<p> 2. The code that destroys (frees) the object can be several lines removed from the place where it is created. Smart pointers allow you to take care of lifetime management right where you create the object.</p>
<p> 3. Even if you are very good at manual memory management, taking care of it is still a chore, and it is always nice to have something, like ARC, or smart pointers, that can take that away from you. It greatly reduces the number of situations where you can make mistakes.</p>
<p> 4. No matter how good you are, you can always <em>forget</em> to call <code>Free</code>, or call <code>LongNamedObjectA.Free</code> when you actually meant <code>LongNamedObjectAB.Free</code>. Such errors are hard to find, especially if they are several lines away from the actual creation spot. Using smartpointers, you don't have to repeat yourself this way, so you can't make such mistakes.</p>
<p><em>So if people tell you that only lazy or incompetent people would use smart pointers, or that people won't be able to understand your code if you use them, don't believe it. They greatly reduce the chance to make mistakes, even if you are competent at manual memory and lifetime management. They remove a lot of clutter and make your code more readable and let you concentrate on what you want to do, not on lifetime management anymore.</em></p>
<h2>Implementation</h2>
<p>I have seen quite a few smart pointer implementations. The nice thing about them is that they take care of automatically destroying the "guarded" object, so you don't have to take care of that yourself. So instead of something like:</p>
<pre><b>var</b>
X: TMyObject;
<b>begin</b>
X := TMyObject.Create(17);
<b>try</b>
<i>// Several lines of code using X</i>
<b>finally</b>
X.Free;
<b>end</b>;
<b>end</b>;</pre>
<p>Now should be able to do something like:</p>
<pre><b>var</b>
X: TMyObject;
<b>begin</b>
X := SmartPointer<TMyObject>(TMyObject.Create(17));
<i>// Several lines of code using X</i>
<b>end</b>;</pre>
<p>And at the end of the function, X is freed automatically.</p>
<h2>Awkward to use</h2>
<p>Unlike what I want to have, most implementations I have seen require you to declare the smart pointers as extra variables:</p>
<pre><b>var</b>
X: TMyObject;
SP: SmartPointer<TMyObject>;
<b>begin</b>
X := SmartPointer<TMyObject>(SP, TMyObject.Create(17));
<i>// Several lines of code using X</i>
<b>end</b>;</pre>
<p>This is so for the <a href="http://blog.barrkel.com/2008/11/reference-counted-pointers-revisited.html"><code>ObjectHandle</code> by Barry Kelly</a>, as well as the <a href="http://wiki.delphi-jedi.org/wiki/JCL_Help:Guard@Pointer@IMultiSafeGuard"><code>ISafeGuard</code> types in the JCL</a>. But I never liked that. It makes you repeat yourself needlessly and makes the code less readable than it could be, taking away one of the advantages smart pointers provide, in my opinion.</p>
<h2>Trick</h2>
<p>So I employ a few tricks. The first one is that if a function or constructor returns a record, and this record is never assigned to a variable, the compiler still puts an anonymous record on the stack. That is because, for any record that is larger than a register, a record that is returned is actually passed as a var parameter. So the following:</p>
<pre><b>function</b> Bla(I, J: Integer): TMyRecord;</pre>
<p>is actually compiled as:</p>
<pre><b>procedure</b> Bla(I, J: Integer; <b>var</b> Result: TMyRecord);</pre>
<p>But that means that an actual record must be passed. If, in your code that uses the function, you don't assign the result of the function, the compiler creates an anonymous record on the stack and passes that, so inside your function you can assign values to the fields of <code>Result</code>.</p>
<p><em>Note that the use of the anonymous record mechanism is <strong>safe</strong>. It is also employed for intermediate results of class operators like + or *. If I use <a href="http://www.rvelthuis.de/programs/bigintegers.html">my <code>BigIntegers</code></a>, or Delphi's sample <code>TComplex</code>, then <code>D := A + B * C;</code> actually produces the code <code>AnonymousIntermediate := op_Multiply(B, C); D := op_Add(A, AnonymousIntermediate);</code> It will not change anytime soon.</em></p>
<p>Here comes the second trick: I want to return a <code>TMyObject</code>, and not a smart pointer record, so I can assign the result directly to <code>X</code>. For this, I (ab)use the <code>Implicit</code> operators you can define for a record. I define a
<pre><b>class operator</b> Implicit(A: TMyObject): SmartPointer<TMyObject>;</pre>
<strong>and</strong> a
<pre><b>class operator</b> Implicit(A: SmartPointer<TMyObject>): TMyObject;</pre>
So if I do the following:</p>
<pre>X := SmartPointer<TMyObject>(TMyObject.Create(17));</pre>
<p>then first, the first <code>Implicit</code> operator returns a record (a smart pointer). This is an anonymous record. But since <code>X</code> is a <code>TMyObject</code>, subsequently the other <code>Implicit</code> operator converts the anonymous record into a <code>TMyObject</code> again. How this "conversion" (actually just some passing around of a reference) is done can be seen in the code a bit further on.</p>
<p>So now I don't have to explicitly declare any smart pointers and can return and assign the created object in one fell swoop. The only thing to take care of is making this generic. That is what I have done in the following simple unit.</p>
<p>Many years ago, I implemented the original smart pointers in the JCL and called them <code>Guards</code>, and I want to remain faithful to that name. But since they are a little "smarter" and easier to use then those early implementations (which did not have overloaded operators or records with methods yet), I called them <code>SmartGuards</code> instead.</p>
<h2>The unit</h2>
<pre><b>unit</b> Velthuis.SmartGuards;
<b>interface
type</b>
IGuard = <b>interface</b>
[<cite>'{CE522D5D-41DE-4C6F-BC84-912C2AEF66B3}'</cite>]
<b>end</b>;
TGuard = <b>class</b>(TInterfacedObject, IGuard)
<b>private</b>
FObject: TObject;
<b>public
constructor</b> Create(AObject: TObject);
<b>destructor</b> Destroy; <b>override</b>;
<b>end</b>;
SmartGuard<T: <b>class</b>> = <b>record</b>
private
FGuard: IGuard;
FGuardedObject: T;
public
<b>class operator</b> Implicit(GuardedObject: T): SmartGuard<T>;
<b>class operator</b> Implicit(Guard: SmartGuard<T>): T;
<b>end</b>;
<b>implementation</b>
<i>{ TGuard }</i>
<b>constructor</b> TGuard.Create(AObject: TObject);
<b>begin</b>
FObject := AObject;
<b>end</b>;
<b>destructor</b> TGuard.Destroy;
<b>begin</b>
FObject.Free;
<b>inherited</b>;
<b>end</b>;
<i>{ SmartGuard<T> }</i>
<b>class operator</b> SmartGuard<T>.Implicit(GuardedObject: T): SmartGuard<T>;
<b>begin</b>
Result.FGuard := TGuard.Create(GuardedObject);
Result.FGuardedObject := GuardedObject;
<b>end</b>;
<b>class operator</b> SmartGuard<T>.Implicit(Guard: SmartGuard<T>): T;
<b>begin</b>
Result := Guard.FGuardedObject;
<b>end</b>;
<b>end</b>.</pre>
<h2>Sample code</h2>
<p>Here is a simple (braindead?) program that uses them. It defines a simple but talkative class that shows when it is being destroyed, and which has a name. The demo shows how it can be used with the <code>SmartGuard</code>.</p>
<pre><b>program</b> SmartGuardDemo;
<i>{$APPTYPE CONSOLE}
{$R *.res}</i>
<b>uses</b>
System.SysUtils,
Velthuis.SmartGuards in <cite>'Velthuis.SmartGuards.pas'</cite>;
<b>type</b>
TTalker = <b>class</b>
<b>private</b>
FName: <b>string</b>;
<b>public
constructor</b> Create(<b>const</b> Name: <b>string</b>);
<b>destructor</b> Destroy; <b>override</b>;
<b>procedure</b> Talk;
<b>end</b>;
<i>{ TTalker }</i>
<b>constructor</b> TTalker.Create(<b>const</b> Name: <b>string</b>);
<b>begin</b>
FName := Name;
<b>end</b>;
<b>destructor</b> TTalker.Destroy;
<b>begin</b>
Writeln(FName, <cite>' is being destroyed'</cite>);
<b>inherited</b>;
<b>end</b>;
<b>procedure</b> TTalker.Talk;
<b>begin</b>
Writeln(FName, <cite>' is talking'</cite>);
<b>end</b>;
<b>procedure</b> Test;
<b>var</b>
A, B: TTalker;
I: Integer;
<b>begin</b>
Writeln(<cite>'Creating object London...'</cite>);
A := SmartGuard<TTalker>(TTalker.Create(<cite>'London'</cite>));
Writeln(<cite>'Creating object Paris...'</cite>);
B := SmartGuard<TTalker>(TTalker.Create(<cite>'Paris'</cite>));
A.Talk;
B.Talk;
Writeln(<cite>'OK, so they talked'</cite>);
<b>for</b> I := 1 <b>to</b> 100 <b>do</b>
Write(I:8);
Writeln;
Writeln;
Writeln(<cite>'Leaving the test'</cite>);
end;
<b>begin</b>
Test;
Readln;
<b>end</b>.</pre>
<h2>Conclusion</h2>
<p>I am sure that these smart pointers could do with some enhancements, and that there could be smart pointers for plain pointers/memory blocks too, or smart pointers that can be stored in lists, arrays, etc. and keep their guarded objects alive for longer than a function. This is just the base frame I have been thinking of.</p>
<p>As was said in the StackOverflow discussion, smart pointers are not a known Delphi idiom. I think that is a pity. But that would require a standard implementation (or a number of them) in the Delphi runtime library. Perhaps one day, we will see them there. Or they will be superseded by ARC. Who knows?</p>
<em>Rudy Velthuis</em>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com9tag:blogger.com,1999:blog-4471683011000431353.post-2522372777033307992017-08-31T20:01:00.000+02:002017-08-31T20:01:13.870+02:00Implicitly imported units in a package.<h2>Problem</h2>
<p>Say, you write a package called <code>MyControls.bpl</code>. The units you put in it need a lot of units from <code>TeeChart</code>:</p>
<p>Package <code>MyControls:</code></p>
<pre>package MyControls;
...
contains
MyUnit1, MyUnit2;
end.
</pre>
<p>Now, in <code>MyUnit1</code> and <code>myUnit2</code>, you use the units <code>TeeThis</code>, <code>TeeThat</code> and <code>TeeOther</code>:</p>
<pre>unit MyUnit1;
uses
TeeThis, TeeThat;</pre>
<pre>unit MyUnit2;
uses
TeeThat, TeeOther;
</pre>
<p>Then these three <code>TeeXXX</code> units will <em>implicitly</em> be imported (linked) into your package. So now your package contains <code>MyUnit1</code>, <code>MyUnit2</code>, <code>TeeThis</code>, <code>TeeThat</code> and <code>TeeOther</code>, although your <code>contains</code> section only <em>explicitly</em> mentions the first two, the ones you wrote.</p>
<p>Then, if a customer of yours installs your package, and then tries to install another package that needs these units too, the IDE will tell them to reference your package, because these units are installed already, <strong>and they can't be in any other package</strong>. That will happen even if your package knows nothing about the other, and the other knows nothing about yours. Because both need the same units.</p>
<h2>Solution</h2>
<p>Instead of implicitly using these units, <em>reference</em> the package that contains them:</p>
<pre>package myControls;
...
contains
MyUnit1, MyUnit2;
requires
TeeChart;
end.
</pre>
<p>Now only your units will be in your package, and the units it needs will be used (referenced) from that other package. This way your package will (probably) be a lot smaller and other packages can use the TeeChart units in the same way.</p>
<h3>Do not forget</h3>
<p>Of course, now you will have to make sure that the user also has the TeeChart package. If you are allowed to distribute it (I guess so, but I am not a lawyer, so read the license), then you can do that and install it if the user doesn't have it installed yet.</p>
<h2>Conclusion</h2>
<p><strong><em>Never, ever, ignore the message that certain units are implicitly imported into your package. Always make sure that this doesn't happen. Instead, reference a package that already contains them.</em></strong> Your packages will be smaller, and there will be no naming conflicts.</p>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-15476754448207450752017-07-04T15:32:00.000+02:002017-07-04T15:33:58.177+02:00Article "Addressing pointers" updated<p>A few years ago, in his <a href="https://wiert.me/2017/06/28/bug-initialisation-of-delphi-record-containing-a-dynamic-array-with-implicit-class-operator-stack-overflow/">Wiert Corner</a>, Jeroen commented that some things were still missing from my article <a href="http://rvelthuis.de/articles/articles-pointers.html">Addressing pointers</a>.</p>
<p>It took me a long time, but now I got around to it and updated the article with info about old Turbo-Pascal-style objects and with procedural types, method types and anonymous methods.</p>
<p>Have "fun" reading.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-2643318717370076922017-05-20T12:30:00.000+02:002017-05-20T12:34:41.436+02:00New article on writing DLLSEspecially on StackOverflow, but also in the Embarcadero forums, I frequently encounter (stupidly) written DLLs, e.g. for hardware or some exotic piece of software that expose things like C++ classes or Delphi AnsiStrings or dynamic arrays. It should have been obvious that such DLLs can not be used by most users who use another language to communicate with the DLL.<br />
<br />
That is why I wrote an article called <a href="http://www.rvelthuis.de/articles/articles-dlls.html">"DLL dos and don'ts"</a> about how I would write DLLs that can be consumed by (almost) every language. I think that it could be a good read for anyone writing DLLs, not just for Delphi users.Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com1tag:blogger.com,1999:blog-4471683011000431353.post-90927095274564909732017-01-01T20:13:00.002+01:002017-11-19T00:22:09.424+01:00BigIntegers and BigDecimals now on GitHub<p>To make it easier for me, as well as for downloaders, I put my <code><a href="http://www.rvelthuis.de/programs/bigintegers.html">BigIntegers</a></code> and <code><a href="http://www.rvelthuis.de/programs/bigdecimals.html">BigDecimals</a></code> code on <em>GitHub</em>.</p>
<p>You can find these and related files (tests, debug visualizers, test data generators, etc.) on my <code><a href="https://github.com/rvelthuis/DelphiBigNumbers">DelphiBigNumbers</a></code> project on <em>GitHub</em>.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-53655219142228964602016-07-18T21:39:00.001+02:002018-01-15T23:16:03.125+01:00New: Velthuis.AutoConsole unit<p>I often (really, very often) write console programs. Most of them are simple test programs to test algorithms, calculations or language features, or stuff copied from <a href="http://stackoverflow.com">StackOverflow</a>.</p>
<p>But console programs, if run from the IDE, or from the Windows Explorer, have one annoying feature: they close immediately if they are finished. So if my program has many <code>Writelns</code> in it, they simply rush by and the console window closes before I can inspect the output. To avoid that, I often put <code>Readln;</code> in the last line of the program. If the program is finished, it pauses and waits for me to press <kbd>Enter</kbd>.</p>
<p>But such a <code>Readln;</code> is annoying if I really want to run the program from an existing console window (aka a Windows command line). Then I don't want to have to press <kbd>Enter</kbd>, because the output is shown in the current console window already, and that won't close until I tell it to.</p>
<p>To get the best of both worlds, I wrote my simple <code>Velthuis.AutoConsole</code> unit. Put it in the <code>uses</code> clause of your console program and, if the program is a console program and it was started from the command line, or if it is not a console program, it will do nothing. But if it is a console program and it was started any other way (from the Windows Explorer, from the Delphi IDE with or without debugger, from another non-console program), then, before the console window can close, it will display:</p>
<pre>Press any key...</pre>
<p>Then I really only have to press a key (it does not have to be <kbd>Enter</kbd>, it can be any key) and the program will end, closing the console Window.</p>
<p>I placed the new unit in the zip for my <a href="http://www.rvelthuis.de/programs/console.html">Console unit</a>. You can download it from the page I linked to.
<p>Here is the code of this simple unit. I think I may have to add a <code>ConsoleCtrlHandler</code>, so the window is not closed when the user presses <kbd>Ctrl</kbd>+<kbd>C</kbd> or closes the console window with the <code style="color: white; background-color: #FF2200; border-radius: 0;"> x </code> close button on the window frame. But I am not sure if that is necessary. If I press those, I usually want to stop the program anyway. <em>Comments on this are welcome</em>.</p>
<pre><b>unit</b> Velthuis.AutoConsole;
<b>interface
implementation
uses</b>
Velthuis.Console, <cite>// as described in the link above</cite>
Winapi.Windows;
<b>function</b> GetConsoleWindow: HWnd; <b>stdcall</b>;
<b>external</b> <i>'kernel32.dll'</i> <b>name</b> <i>'GetConsoleWindow'</i>;
<b>function</b> StartedFromConsole: Boolean;
<b>var</b>
ConsoleHWnd: THandle;
ProcessId: DWORD;
<b>begin</b>
ConsoleHwnd := GetConsoleWindow;
<b>if</b> ConsoleHWnd <> 0 <b>then
begin</b>
GetWindowThreadProcessId(ConsoleHWnd, ProcessId);
Result := GetCurrentProcessId <> ProcessId;
<b>end
else</b>
Result := False;
<b>end</b>;
<b>procedure</b> Pause;
<b>begin
if</b> IsConsole <b>and not</b> StartedFromConsole <b>then
begin</b>
Write(<em>'Press any key... '</em>);
ReadKey;
<b>end</b>;
<b>end</b>;
<b>initialization
finalization</b>
Pause;
<b>end</b>.
</pre>
<h3>Update</h3>
<p>I removed the reliance on the <code>Velthuis.Console</code> unit. I added this piece, a simplified version of <code>ReadKey</code>, which does not try to translate the key, making things a lot simpler:</p>
<pre><b>procedure</b> WaitForInput;
<b>var</b>
InputRec: TInputRecord;
NumRead: Cardinal;
OldKeyMode: DWORD;
StdIn: THandle;
<b>begin</b>
StdIn := GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(StdIn, OldKeyMode);
SetConsoleMode(StdIn, 0);
<b>repeat</b>
ReadConsoleInput(StdIn, InputRec, 1, NumRead);
<b>until</b> (InputRec.EventType <b>and</b> KEY_EVENT <> 0) <b>and</b> InputRec.Event.KeyEvent.bKeyDown;
SetConsoleMode(StdIn, OldKeyMode);
<b>end</b>;</pre>
<p>and changed the <code>Pause</code> procedure a little:</p>
<pre><b>procedure</b> Pause;
<b>begin
if</b> IsConsole <b>and not</b> StartedFromConsole <b>then
begin</b>
Write(<em>'Press any key... '</em>);
WaitForInput;
<b>end</b>;
<b>end</b>;</pre>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com3tag:blogger.com,1999:blog-4471683011000431353.post-67875300789030978352016-05-20T17:07:00.000+02:002016-05-21T12:26:51.462+02:00New blogging site<p>The blog that I had on the TeamB site is not functional anymore. I guess that is because it was still hosted by Borland, as far as I know. My blog pages were moved to the new Embarcadero Community site, but all comments were lost (sorry folks, but I had nothing to do with this), my user name is listed as "Rudy Velthuis Velthuis (TeamB)" and there seems to be nothing I can do to change this. And a search for "Rudy" or "Velthuis" on the Bloggers page doesn't find it either, or well, it says it found one instance, but it doesn't show it.</p>
<p>But what is worse, I can't write, edit or administer the posts there. That is why I decided to reactivate this blog site, which I had reserved ages ago. I have complete control over what I post here. I managed to copy most posts from the Community site over, and updated the formatting where that was necessary.</p>
<p>So please, if you had any links to my old blog, please update them to point to this site. The <a href="http://blogs.teamb.com/rudyvelthuis">old URL</a> will redirect to the Community site, but I will probably not be using that anymore. I hope that it will be picked up by <a href="http://www.delphifeeds.com/">DelphiFeeds</a> and similar sites soon, because I intend to write regular blog posts again.</p>
<h3>Update</h3>
<p>I was told that the glitches and problems with the moved blogs on the Community server are going to be solved, and that the site will be made faster as well. They'll even try to re-install the comments. If that is the case, I will move back to the Community site again. Hang on.</p> Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-14088018696264049862016-04-10T19:46:00.000+02:002016-05-05T03:26:38.930+02:00New: BigDecimalsAfter <a href="http://rvelthuis.de/programs/bigintegers.html">BigIntegers</a>, the next logical step was the implementation of <a href="http://rvelthuis.de/programs/bigdecimals.html">BigDecimals</a>. I implemented them using BigIntegers, because a BigDecimal is not much more than a BigInteger divided (or multiplied) by - scaled by - a power of 10.<br>
<br>
Unlike BigIntegers, my implementation of BigDecimals does not use any assembler, so it should be usable anywhere BigIntegers can be used.<br>
<br>
The BigDecimals are mostly modelled after the interface of the BigDecimal class in Java, but, like BigIntegers, made more Delphi-like. Java BigDecimals do not support operator overloading, while my BigDecimals do. This makes the handling of rounding and precision a little different too.<br>
<br>
Anyway, I think that every Delphi should not only have BigIntegers, but BigDecimals too. Have fun with them. They can be found in the same .zip file as BigIntegers. Just read more about them <a href="http://rvelthuis.de/programs/bigdecimals.html">on my website</a>.<br>
<br>
The next step is BigDecimal math, like trigonometric, exponential functions etc. One other step will be to host this on GitHub. I am also thinking of writing prime, factorization and other mathematically useful functions for BigIntegers.
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com1tag:blogger.com,1999:blog-4471683011000431353.post-41458959165239332202016-02-01T21:54:00.000+01:002016-05-05T03:25:59.067+02:00In Delphi, is addition commutative?<p>Answer: <em>no, not necessarily</em>. Despite the existence of operator precedence, i.e. the fact that the following</p>
<pre> X := 3 + 4 * 5;</pre>
<p>results in 23 and not in 35, the order of operands can still have an effect.</p>
<p>In my <a href="http://www.rvelthuis.de/programs/bigintegers.html">BigInteger</a> code, I discovered an odd error, that only happened in some very rare cases, and only in <code>PUREPASCAL</code> code, i.e. code that did not use assembler, and only in 64 bit.</p>
<p>It took me several hours to find out that this was the problematic expression:</p>
<pre> Value := NormDividend[I + J] + NormDivisor[I] + Value <b>shr</b> CDivLimbBits;</pre>
<p><code>CDivLimbBits</code> is a constant with value 32, <code>Value</code> is an <code>Int64</code>, <code>NormDividend[]</code> and <code>NormDivisor[]</code> are arrays of <code>UInt32</code> (<code>Cardinal</code>). Only in some very special circumstances, this caused an error. </p>
<h3>What happened?</h3>
<p>In this unit, which does lots of odd and ugly things to <code>UInt32</code>s and to speed things up, I turned off range and overflow checks, so it went unnoticed that <code>NormDividend[I + J] + NormDivisor[I]</code> caused an overflow. Since overflow and range checks were off, the 33rd bit simply got cut off.</p>
<p>But you might say: "Hey, the third operand is an Int64, so why were these two operands not promoted to 64 bit?" It turns out that this only happens once it is required, so what the compiler actually compiles is:</p>
<pre> UInt32(Intermediate) := UInt32(NormDividend[I + J]) + UInt32(NormDivisor[I]);
Value := Int64(Intermediate) + Value <b>shr</b> 32;
</pre>
<p>while I expected:</p>
<pre> Value := Int64(NormDividend[I + J]) + Int64(NormDivisor[I]) + Value <b>shr</b> 32;</pre>
<p>Now, if you rearrange the <code>Int64</code> to come first, like:</p>
<pre> Value := Value <b>shr</b> 32 + NormDividend[I + J] + NormDivisor[I];</pre>
<p>then all is well. The first operand is an <code>Int64</code>, so all following operands are promoted too and you really get:</p>
<pre> Value := Value <b>shr</b> 32 + Int64(NormDividend[I + J]) + Int64(NormDivisor[I]);</pre>
<p>Note that this error did not happen in 32 bit code. There, <code>NormDividend[]</code> and <code>NormDivisor[]</code> are arrays of <code>UInt16</code>, and <code>Value</code> is an <code>Int32</code>. In other words, in 32 bit code (and even in 64 bit code on Windows), everything seems to be promoted to <code>Int32</code> (signed 32 bit integer) anyway, probably because that type is somehow the preferred type for integer expressions (most integer code uses 32 bit registers, in 32 bit as well as in 64 bit).</p>
<p>So take care to either cast to the required type, or to put the largest operand first, otherwise you might be in for a surprise. It certainly was a surprise to me, especially because the data I had used for unit testing had not caught this.</p>
<p>Only the fact I wanted to improve the speed of <code>ToString</code> (converting the largest known prime to a string of 22 million decimal digits still takes approx. 2'30", while converting it to a string of — much more easily convertible — hex digits only takes 135 ms), and the coincidence that in one test I had to divide by exactly 10^57, made me catch this error. Note that the assembler code did not suffer from this. There I can control exactly what gets promoted and when.</p>
<p>This also made me aware again of the fact that testing can only show the presence of errors, and never the absence, and that it is extremely hard to find test cases that cover everything. The fact I had to divide by a number that caused the error was sheer coincidence.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-29569051746084958252015-11-19T22:46:00.000+01:002016-05-05T03:26:27.116+02:00New: BigIntegers<p>I wrote a new implementation of BigIntegers (almost unlimited size integers) for Delphi. It uses assembler for the low level stuff, although there is a PUREPASCAL version for each of these routines too. Instead of using the GPL-licensed GNU Multi-Precision (GMP) library, I wrote everything from scratch, without using any code from others.</p>
<p>I think it is pretty fast, especially because I optimized many of the routines, either by techniques like loop unrolling or using 64 bits at once, or by using bitwise tricks, or by high-level algorithms like <em>Burnikel-Ziegler</em>, <em>Karatsuba</em>, <em>Toom-Cook 3-way</em>, etc. Results are checked with results generated by .NET. The C# test program is included.</p>
<p>In the course of writing this, I read an enormous numbers of publications on these subjects and I learned a lot, not only about the maths involved, but also about many other mathematical notions. Not so easy for a dentist. I also had some good help on StackOverflow.</p>
<p>Go take a look at <a href="http://rvelthuis.de/programs/bigintegers.html">my website</a>. I think every Delphi should have BigIntegers.</p>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-32471005839532494152015-10-04T23:19:00.000+02:002018-01-20T13:52:47.892+01:00Speed problems caused by code that never ran<p>Let me start out by telling you that I am currently implementing a (simple) BigInteger implementation for Delphi. This implementation tries to be compatible with the BigIntegers as used in .NET, so I can test my results to be the same as the results of my tests in C#.</p>
<p>For this, <code>RightShift</code> must use two's complement semantics, and shifting a negative integer must shift in 1-bits from the top, so <code>-100</code> (<code>$FFFFFF9C</code>) shifts to <code>-50</code> (<code>hex $FFFFFFCE</code>). For normal <code>Integer</code> values, the result in Delphi would be <code>2147483598</code> (hex <code>$7FFFFFCE</code>), because Delphi does a simple shift and does not preserve the sign bit. But my BigIntegers should, because most other Biginteger implementations (including the .NET one, my reference) do that too.</p>
<p>To achieve this, in my routine, I did something like this:</p>
<pre><strong>class operator</strong> BigInteger.RightShift(<strong>const</strong> Value: BigInteger;
Shift: Integer): BigInteger;
<strong>var</strong>
LSize: Integer;
ShiftOffset: Integer;
RSize: Integer;
P: PLimb;
<strong>begin
if</strong> Value.IsZero <strong>then</strong>
Exit(BigInteger.Zero);
<strong>if</strong> Value.IsPositive <strong>then
begin</strong>
<em>// Call internal methods that allocate the result, shift the value right, etc.
// Works fine, no problem.</em>
<strong>end
else
begin</strong>
<em>// Recursive call</em>
Result := MinusOne - ((MinusOne - Value) <strong>shr</strong> Shift);
<strong>end</strong>;
<strong>end</strong>;</pre>
<p>That gave me the right results, so I was happy until I started benchmarking the new routine. I noticed that the right shift was more than twice as slow as the corresponding left shift. I did not understand this, because a right shift actually has to move fewer bits and the result is smaller. Even if I only passed in positive values, it would still be slow. The code was almost the same as the code for left shift, though. Well, except for the <code>else</code> clause.</p>
<p>People cleverer than I am probably already see the problem: the "negative" branch (the <code>else</code> clause) of the <code>if</code> clause. When I removed it, code was indeed <em>faster</em> than that for left shifts. But when I put it back in, even though it would never run, it slowed down everything. Only after some hard thinking and some debugging I noticed, in the CPU view, that there were calls to <code>InitializeArray</code> and <code>FinalizeArray</code> in the compiled routine, and that everything was surrounded by a <code>try-finally</code> block. The expression in the "negative" branch had some intermediate results, and records for these were allocated and managed by the runtime. That made the entire code slow.</p>
<h4>First solution</h4>
<p>My first solution was to put the code for the "negative" branch into a nested procedure of its own. The hidden local BigIntegers were now confined in that procedure and would not cause the entire routine to be slow. The "positive" part was indeed up to speed now.</p>
<p>I finally deconstructed <code>Result := MinusOne - ((MinusOne - Value) shr Shift);</code> into internal calls entirely, so no hidden BigIntegers were allocated anymore. Now I could put the "negative" code back from the nested procedure to the negative branch, and it was quite a bit faster as well.</p>
<h3>Conclusion</h3>
<p>I learned two things from this:</p>
<ul>
<li>Beware of hidden code. Here, it was caused by the expression with intermediate results.</li>
<li>Inline with caution. If I had inlined the nested routine, the hidden BigIntegers would have been put back in the outer scope, and things would have been slow again.</li>
</ul>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-6793924915457117112006-10-04T23:35:00.000+02:002016-05-05T03:27:05.217+02:00Delphi for .NET namespaces misunderstood?<h2>Confusion</h2>
<p>There seems to be a big confusion about Delphi for .NET namespaces. I guess this is because there was a big change between Delphi 8 and Delphi 2005.</p>
<p>In Delphi 8, each unit was its own namespace. In Delphi 2005, several units can be placed in the same namespace, by prefixing the unit name with the namespace name. You can even add to an existing namespace in an assembly not written in Delphi for .NET.</p>
<p>I often see the argument that namespaces in Delphi for .NET are non-standard. But since you can create a namespace consisting of several units, in several assemblies, there is in fact no big difference for other .NET languages. To the "outside" world, i.e. to non-Delphi code, they are as standard as they should be.</p>
<p>IOW, if you have units <em>Rudy.Velthuis.Labels</em>, <em>Rudy.Velthuis.EditBoxes</em>, and <em>Rudy.Velthuis.Memos</em> they make up the namespace Rudy.Velthuis, and can be used as such from any non- Delphi .NET language. (FWIW, if your namespace is only meant to contain VCL.NET classes, I see no reason not to use the VCL terminology, i.e. prefix types with T, etc. If your assembly is meant to be used by other languages, then follow the .NET guidelines on naming.)</p>
<p>What is different is that Delphi for .NET internally has the <em>advantage</em> that you don't include an entire namespace, filling up the scope with a lot of unnecessary identifiers, but only the units you need. This is IMO a big advantage. If you only need Labels, but not EditBoxes or Memos, you only put Rudy.Velthuis.Labels in your <strong>uses</strong> clause. I'll explain why this is IMO a <em>Good Thing™</em></p>
<p>Any good C++ programmer will frown upon the practice of including entire namespaces into the scope. A good C++ programmer will not use</p>
<pre><b>using namespace</b> std;</pre>
<p>but will simply qualify each identifier from that namespace with the explicit <strong>std::</strong> prefix. For the same reason, Modula 2 users can import entire modules, but are encouraged to only import the identifiers they need. Delphi for .NET's scope resolution is not that fine grained, but at least it offers units, instead of the inclusion of entire namespaces. Of course this only works with Delphi-written namespaces.</p>
<p>The fact that namespaces are disconnected from physical file names is perhaps not a problem for a compiler (well, it actually is a small problem, since it makes it have to look up and remember — store — a lot more identifiers, which makes it slower), but it is a problem for the humans who have to use them. I am glad that Delphi keeps the connection between compilation unit and logical unit.</p>
<h2>Conclusion</h2>
<p>So, to recap:</p>
<ul>
<li>Delphi namespaces are extensible, like in other .NET languages. Several units can make up a namespace, and units can be added to one. They are perhaps non-standard internally, but to the outside .NET world, they are no different than a VB or C# namespace.</li>
<li>Delphi namespaces are usable by other languages as one namespace, no matter how many units it contains.</li>
<li>Internally, when Delphi uses Delphi-written namespaces, Delphi has the added advantage that you don't have to include entire namespaces at once, but have a finer grained scoping mechanism.</li>
<li>Delphi units are IMO easier to use than namespaces consisting of several source files and spread over several assemblies.</li>
</ul>
<em>Rudy Velthuis</em>Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0tag:blogger.com,1999:blog-4471683011000431353.post-29050753217026921782005-12-22T18:00:00.000+01:002016-05-05T03:27:37.035+02:00Delphi constructors with different names, when used in C++Builder<p>The integration of C++Builder and Delphi seems to have caused a few problems for those of us who write components or classes in Delphi, and then want to use these in C++Builder. There are a few things one should avoid when one writes classes (see below), and the symbol BCB doesn't seem to be defined when the Delphi compiler is called from C++Builder.</p>
<p>Some of the things one should not do are mentioned on the <a href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/jvcl/dev/JVCL3/help/BCB%20Compatibility%20Guide.html">JVCL sourceforge pages</a>.</p>
<p>One other thing is something I discussed elsewhere with someone. In Delphi, it is not unusual to create multiple constructors with different names which tell the user what they do.</p>
<p>A simple example I concocted up is below:</p>
<pre><b>unit</b> GraphicVectors;
<b>interface
uses</b>
SysUtils, Classes;
<b>type</b>
TGraphicVector = <b>class</b>(TObject)
<b>public
constructor</b> Create(X, Y: Double);
<b>end</b>;
TPolarVector = <b>class</b>(TGraphicVector)
<b>public
constructor</b> CreatePolar(Radial, Theta: Double);
<b>end</b>;
<b>implementation</b></pre>
<p>This defines <code>TGraphicVector</code>, which takes two Cartesian coordinates, <code>X</code> and <code>Y</code>, both of type <code>Double</code>. And a descendant <code>TPolarVector</code>, which is internally almost the same, but can be defined using polar coordinates. So <code>TPolarVector</code> has two constructors, the one inherited from <code>TGraphicVector</code>, and <code>CreatePolar</code>, which accepts polar coordinates.</p>
<h3>Constructors which differ only in name</h3>
<p>Problem is, that both have two parameters of type <code>Double</code>. In Delphi, this is not a problem, because the constructors have different names. But C++ constructors do not have any names of their own. They get the name of the class for which they are defined.</p>
<p>So the <var>.hpp</var> file for the unit above contains this, for <code>TPolarVector</code>:</p>
<pre><b>class</b> DELPHICLASS TPolarVector;
<b>class</b> PASCALIMPLEMENTATION TPolarVector : <b>public</b> TGraphicVector
{
<b>typedef</b> TGraphicVector inherited;
<b>public:
__fastcall</b> TPolarVector(<b>double</b> Radial, <b>double</b> Theta);
<b>public</b>:
<em><i>#pragma option push -w-inl</i></em>
<i>/* TGraphicVector.Create */</i> <b>inline __fastcall</b>
TPolarVector(<b>double</b> X, <b>double</b> Y) : TGraphicVector(X, Y) { }
<em><i>#pragma option pop</i></em>
<b>public</b>:
<em><i>#pragma option push -w-inl</i></em>
<i>/* TObject.Destroy */</i> <b>inline __fastcall virtual</b> ~TPolarVector(<b>void</b>) { }
<em><i>#pragma option pop</i></em>
};</pre>
<p>You can see the problem above: there are two constructors <code>TPolarvector(double, double)</code>. The first is <code>TPolarvector.CreatePolar</code>, the second is <code>TGraphicVector.Create</code>, which must be redeclared as <code>TPolarVector</code> to make it a constructor for <code>TPolarVector</code> as well. C++ does not allow two constructors with the same signature, so you will get two errors for the second declaration:</p>
<blockquote>[C++ Error] GraphicVectors.hpp(49): E2238 Multiple declaration for '_fastcall TPolarVector::TPolarVector(double,double)'<br /><br />
[C++ Error] GraphicVectors.hpp(46): E2344 Earlier declaration of '_fastcall TPolarVector::TPolarVector(double,double)'</blockquote>
<h3>Conclusion</h3>
<p>So, apart from what the JVCL pages describe, you should also avoid using constructors with the same signature but differing in name. It is best if you simply do not use any other constructor name than Create. If you need more than one, be sure to use the overload directive.</p>
<em>Rudy Velthuis</em>
Rudy Velthuishttp://www.blogger.com/profile/04591719175507325825noreply@blogger.com0