<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Delphi &#8211; void</title>
	<atom:link href="http://boku.ru/category/computers/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://boku.ru</link>
	<description>Склад полезных заметок</description>
	<lastBuildDate>Fri, 03 Jul 2015 20:59:59 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Solved: Delphi XE3 64-bit debugger fails to run</title>
		<link>http://boku.ru/2015/07/03/solved-delphi-xe3-64-bit-debugger-fails-to-run/</link>
					<comments>http://boku.ru/2015/07/03/solved-delphi-xe3-64-bit-debugger-fails-to-run/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Fri, 03 Jul 2015 11:49:55 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[In English @en]]></category>
		<guid isPermaLink="false">http://www.boku.ru/?p=11524</guid>

					<description><![CDATA[
Symptoms: Delphi XE3 sometimes fails to run 64-bit applications under a debugger. Code would compile, but the part where Delphi switches to debug layout never happens, Delphi just pops a message saying &#38;quot;Cannot run the debugger&#38;quot;. 32-bit debugging continues to work normally, and so does &#38;quot;Run without debugging&#38;quot;. The funny part is that this happens [&#38;hellip;]
]]></description>
										<content:encoded><![CDATA[<h3>Symptoms:</h3>
<p>Delphi XE3 sometimes fails to run 64-bit applications under a debugger. Code would compile, but the part where Delphi switches to debug layout never happens, Delphi just pops a message saying &quot;Cannot run the debugger&quot;.</p>
<p>32-bit debugging continues to work normally, and so does &quot;Run without debugging&quot;.</p>
<p>The funny part is that this happens irregularly. Sometimes the first attempt would succeed, and then the debugger would run all the time in all instances of Delphi. But if it fails the first time then it would always fail even if you restart Delphi.</p>
<p>I also noticed that the earlier I launch Delphi + debugger, the higher is the chance it would run (and then continue working). It seemed like there was something I was doing or the computer was doing sometime after boot that broke the debugger if I hadn&#039;t launched it yet.</p>
<h3>Solution:</h3>
<p>Stop the &quot;Internet connection sharing&quot; service and restart Delphi.</p>
<h3>What might have contributed:</h3>
<p>&#8211; Uninstalling older versions of Delphi on the same PC.<br />
&#8211; Disabling Windows Firewall<br />
&#8211; Disabling Windows Defender</p>
<p><a name="more-11524-2" /><a href="http://boku.ru/2015/07/03/solved-delphi-xe3-64-bit-debugger-fails-to-run/#more-11524-2" id="more-stub-11524-2" class="more-stub" onclick="expand_more('11524-2'); return false;">(Diagnostics process)</a></p>
<div id="more-content-11524-2" class="more-content">
<h3>Diagnostics process:</h3>
<p>Looking at the successful and failed debugger launches with Process Monitor, in both cases Delphi runs a remote debugger. But on the successful run it&#039;s <code>dbkw64_17_0.exe</code> (64 bit) while failed runs spawn <code>rmtdbg170.exe</code> (32 bit). Both are Delphi debuggers, but I suspected that the second one is only supposed to be used for 32 bit debugging.</p>
<p>Further investigation showed that in both cases <code>dbkw64_17_0.exe</code> launches initially, but in the second case it terminates shortly afterwards. Delphi then tries to connect to it through TCP, unable to do so, and restarts it automatically. But the code that does the restart probably wasn&#039;t updated to 64 bit and launches 32-bit <code>rmtdbg170.exe</code> instead.</p>
<p>Anyway, the problem lies in the initial instance of <code>dbkw64_17_0.exe</code> terminating. Comparing Process Monitor logs, both successful and failed runs load the libraries and then work with winsock. Stack in the final calls indicates <code>ws2_32.dll</code>&#039;s <code>socket()</code> is running &#8211; the debugger is probably trying to open it&#039;s command socket for listening &#8211; after which failed instance abruptly terminates (Thread Exit, Process Exit). I figured <code>socket()</code> probably returns with an error.</p>
<p>Using rohitab&#039;s Api Monitor I tried to find out the error code, but this didn&#039;t work out. Api Monitor successfully traced all the calls until roughly <code>WSAStartup()</code>, but no further &#8211; the last bunch of calls just before the termination always got lost, perhaps the injected driver wasn&#039;t being able to send it back to the main app in time before the application terminated.</p>
<p>Then I opened <code>dbkw64_17_0.exe</code> for debugging in Visual Studio. I set a breakpoint to <code>{,,ws2_32.dll}socket</code>, caught the execution there and studied what happens step by step. Turns out, <code>socket()</code> was successful. It was followed by <code>setsockopt</code> call, also successful (to know which functions we were stepping into, I used VS&#039;s standard ability to load Windows DLL symbols from Microsoft servers). Then <code>dbkw64_17_0.exe</code> called <code>bind()</code> which failed.</p>
<p>My initial guess was that someone else occupied the port it needed. Checking <code>bind()</code> parameters at MSDN, I looked into <code>RDX, RCX, R8, R9</code> registers which host parameters in x64 calls, namely the memory referenced by <code>RCX</code>, which kept the requested family and port number. It turned out to be 0xC0F3 but it was unoccupied.</p>
<p>I then traced the call to <code>bind()</code> and from the internal call to <code>WSPBind()</code> got the error code: 0x1D27, that is 10013 (WSAEACCES: Permission denied. An attempt was made to access a socket in a way forbidden by its access permissions).</p>
<p>This code has no single specific reason for it. From the internet it looks like it appears when some driver or network-related service misbehaves. I tried stopping network related services one by one, until finally <code>bind()</code> succeeded. The infringing service was &quot;Internet connection sharing (ICS)&quot;. As long as I stop this service, the debugger launches normally, and so long as ICS is running, the debugger would not start.</p>
<p>The reason why sometimes the debugger would run and then run always, is probably that ICS hadn&#039;t yet been started or did not yet harm the network stack at the time. If the debugger run at that point, it would bind the socket, and for whatever reason binding at that port would then continue working later. But if the debugger was initially launched <i>after</i> the harm has been done, it wouldn&#039;t be able to bind to the port neither once nor at all.</div>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2015/07/03/solved-delphi-xe3-64-bit-debugger-fails-to-run/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>HOWTO: Assign checkable TAction to TSpeedButton</title>
		<link>http://boku.ru/2014/07/23/howto-assign-checkable-taction-to-tspeedbutton/</link>
					<comments>http://boku.ru/2014/07/23/howto-assign-checkable-taction-to-tspeedbutton/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Wed, 23 Jul 2014 11:59:10 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[In English @en]]></category>
		<guid isPermaLink="false">http://www.boku.ru/?p=11084</guid>

					<description><![CDATA[
To make TSpeedButton work with TAction.Checked when it&#38;#039;s a singular option (either On or Off), make sure that at design-time: SpeedButton.Action = Action SpeedButton.GroupIndex = 0 SpeedButton.AllowAllUp = true Action.GroupIndex = 0 Action.AutoCheck = true <em>only if you need AutoCheck Then add this to FormCreate: SpeedButton.GroupIndex := 17; </em>any non-used group index SpeedButtons are linked [&#38;hellip;]
]]></description>
										<content:encoded><![CDATA[<p>To make TSpeedButton work with TAction.Checked when it&#039;s a singular option (either On or Off), make sure that at design-time:</p>
<p><code>SpeedButton.Action = Action<br />
SpeedButton.GroupIndex = 0<br />
SpeedButton.AllowAllUp = true<br />
Action.GroupIndex = 0<br />
Action.AutoCheck = true //only if you need AutoCheck</code></p>
<p>Then add this to <code>FormCreate</code>:</p>
<p><code>SpeedButton.GroupIndex := 17; //any non-used group index</code></p>
<p>SpeedButtons are linked to Actions through TSpeedButtonActionLink. It only updates their Down property if AllowAllUp is set and SpeedButton.GroupIndex property is NOT 0.</p>
<p>But when Action is linked, SpeedButton.GroupIndex gets rewritten by Action.GroupIndex on load.</p>
<p>And if Action.GroupIndex is 0 because it&#039;s a singular option, then no matter what you put into SpeedButton.GroupIndex at design-time, it&#039;s going to be rewritten with 0 at load, so TSpeedButtonActionLink does not update Down property.</p>
<p>The simplest solution is to set SpeedButton.GroupIndex to something in FormCreate.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2014/07/23/howto-assign-checkable-taction-to-tspeedbutton/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Multiobject try..finally</title>
		<link>http://boku.ru/2013/05/25/multiobject-try-finally/</link>
					<comments>http://boku.ru/2013/05/25/multiobject-try-finally/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Sat, 25 May 2013 19:35:09 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[In English @en]]></category>
		<guid isPermaLink="false">http://www.boku.ru/?p=8786</guid>

					<description><![CDATA[
Just a simple Delphi pattern. We all have encountered nested try..finally blocks like this: CChar := TTextTableCursor.Create(TChar); try CCharProp := TTextTableCursor.Create(TCharProp); try Builder := TCharPropBuilder.Create(Result); try <em>Do some work with all three objects </em>Since all three are needed, we can&#38;#039;t destroy any before this point finally FreeAndNil(Builder); end; finally FreeAndNil(CCharProp); end; finally FreeAndNil(CChar); end;But there&#38;#039;s [&#38;hellip;]
]]></description>
										<content:encoded><![CDATA[<p>Just a simple Delphi pattern. We all have encountered nested <code>try..finally</code> blocks like this:<br />
<code></p>
<pre>CChar := TTextTableCursor.Create(TChar);
try
<pre>
 CCharProp := TTextTableCursor.Create(TCharProp);
 try
   Builder := TCharPropBuilder.Create(Result);
   try
     //Do some work with all three objects
     //Since all three are needed, we can&#039;t destroy any before this point
   finally
     FreeAndNil(Builder);
   end;
 finally
   FreeAndNil(CCharProp);
 end;
</pre>
<p>finally</p>
<pre>
 FreeAndNil(CChar);
</pre>
<p>end;</code>But there&#039;s a nicer way of doing the same while still being exception safe (and avoiding the overhead of three <code>try..finally</code> exception frames):<br />
<code></p>
<pre>CChar := nil;
CCharProp := nil;
Builder := nil;
try
<pre>
 CChar := TTextTableCursor.Create(TChar);
 CCharProp := TTextTableCursor.Create(TCharProp);
 Builder := TCharPropBuilder.Create(Result);
//Do some work with all three objects
</pre>
<p>finally</p>
<pre>
 FreeAndNil(Builder);
 FreeAndNil(CCharProp);
 FreeAndNil(CChar);
</pre>
<p>end;</code></p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2013/05/25/multiobject-try-finally/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Installing Delphi VersionInsight Plus</title>
		<link>http://boku.ru/2013/05/22/installing-delphi-versioninsight-plus/</link>
					<comments>http://boku.ru/2013/05/22/installing-delphi-versioninsight-plus/#comments</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Wed, 22 May 2013 13:44:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[In English @en]]></category>
		<category><![CDATA[Компьютеры]]></category>
		<guid isPermaLink="false">http://www.boku.ru/?p=8780</guid>

					<description><![CDATA[
Since Delphi XE, Delphi has SVN support integrated into file history display. SVN revisions are displayed in addition to local backups, all properly sorted by date. Very nice. Mercurial and Git support wasn&#38;#039;t added into the default distribution, but there&#38;#039;s a newer version of VersionInsight plugin with fully functioning support for those, written by Delphi [&#38;hellip;]
]]></description>
										<content:encoded><![CDATA[<p>Since Delphi XE, Delphi has SVN support integrated into file history display. SVN revisions are displayed in addition to local backups, all properly sorted by date. Very nice.</p>
<p>Mercurial and Git support wasn&#039;t added into the default distribution, but there&#039;s a newer version of VersionInsight plugin with fully functioning support for those, written by Delphi developers. Meet <b><a href=http://sourceforge.net/projects/radstudioverins/>RAD Studio Version Insight Plus</a></b>.</p>
<p>To use this you need to compile it. It&#039;s simple, but mind these fine points:</p>
<ul>
<li>There are several branches in the repo, you need the <code>/plus</code> one. Not the trunk.</li>
<li>Delphi less than XE will not compile those, no simple solution.</li>
<li>You need to compile five packages: <code>svn</code>, <code>svnui</code>, <code>svnide</code> (already grouped into DelphiSVN) + <code>hgide</code> and <code>gitide</code>.</li>
<li>Delphi already includes pre-compiled <code>svn</code>, <code>svnui</code> and <code>svnide</code>. You need to remove those from &quot;Component&gt; Install packages&quot; list. (And restart)</li>
<li>The ones from SVN are marked ver_150, and the ones with Delphi ver_170, but the ones from SVN are newer (I think).</li>
<li>When compiling the packages, Delphi might try to trip you up and use existing packages it cached somewhere instead of the sources right in front of it.<br />To be on a safe side, do <code>dir c:\svn*.bpl /s</code>, <code>dir c:\svn*.dcp /s</code>, <code>dir c:\svn*.dcu /s</code>, and remove everything related to VersionInsight plus. (Some matches are going to be in the cached Delphi install distributions, these are fine).<br />Particularly, <code>svn*.dcp</code> in <code>Program Files\Embarcadero\Delphi\DelphiVersion\lib\Win32\debug</code> or <code>\release</code> are known to silently cause problems such as <code>svnui.bpl</code> complaining that TSvnBlameOptions is not defined even though it&#039;s defined right there in <code>SvnClient.pas</code>.</li>
</ul>
<p>Otherwise packages compile just fine, have no dependencies and produce almost no warnings.</p>
<p>After compiling the packages, install the last three (<code>svnide</code>, <code>hgide</code> and <code>gitide</code>). Restart the Delphi.</p>
<p>The SVN support will start working straight away (it should have been working before too). For Git and Mercurial you need to go to Tools&gt; Options&gt; Version Control, and set paths to <code>git.exe</code> and <code>hg.exe</code> executables in the respective sections.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2013/05/22/installing-delphi-versioninsight-plus/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Про паскаль</title>
		<link>http://boku.ru/2013/02/14/%d0%bf%d1%80%d0%be-%d0%bf%d0%b0%d1%81%d0%ba%d0%b0%d0%bb%d1%8c/</link>
					<comments>http://boku.ru/2013/02/14/%d0%bf%d1%80%d0%be-%d0%bf%d0%b0%d1%81%d0%ba%d0%b0%d0%bb%d1%8c/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Thu, 14 Feb 2013 10:21:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<guid isPermaLink="false">http://www.diary.ru/~himself/p185420229.htm</guid>

					<description><![CDATA[&#1045;&#1089;&#1083;&#1080; &#1089;&#1095;&#1080;&#1090;&#1072;&#1090;&#1100;, &#1095;&#1090;&#1086; &#1087;&#1072;&#1089;&#1082;&#1072;&#1083;&#1100; &#1074;&#1099;&#1084;&#1080;&#1088;&#1072;&#1077;&#1090;, &#1090;&#1086; &#1074;&#1099;&#1084;&#1080;&#1088;&#1072;&#1090;&#1100; &#1086;&#1085; &#1091;&#1084;&#1091;&#1076;&#1088;&#1103;&#1077;&#1090;&#1089;&#1103; &#1089; &#1086;&#1075;&#1086;&#1085;&#1100;&#1082;&#1086;&#1084;. &#1059; &#1085;&#1072;&#1089; &#1077;&#1089;&#1090;&#1100; Delphi, &#1082;&#1086;&#1090;&#1086;&#1088;&#1099;&#1081; &#1087;&#1088;&#1080; &#1074;&#1089;&#1077;&#1093; &#1087;&#1088;&#1086;&#1073;&#1083;&#1077;&#1084;&#1072;&#1093; &#1091;&#1087;&#1088;&#1072;&#1074;&#1083;&#1077;&#1085;&#1080;&#1103; &#1087;&#1086;&#1089;&#1090;&#1086;&#1103;&#1085;&#1085;&#1086; &#1074;&#1074;&#1086;&#1076;&#1080;&#1090; &#1082;&#1088;&#1091;&#1090;&#1099;&#1077; &#1074;&#1086;&#1079;&#1084;&#1086;&#1078;&#1085;&#1086;&#1089;&#1090;&#1080; &#1074; &#1103;&#1079;&#1099;&#1082;. &#1054;&#1085; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1080;&#1088;&#1091;&#1077;&#1090;&#1089;&#1103; &#1087;&#1086;&#1076; win-x32, win-x64 &#1080; &#1084;&#1072;&#1082;&#1080;. &#1045;&#1089;&#1090;&#1100; FreePascal, &#1082;&#1086;&#1090;&#1086;&#1088;&#1099;&#1077; &#1087;&#1086;&#1076;&#1076;&#1077;&#1088;&#1078;&#1080;&#1074;&#1072;&#1077;&#1090; &#1073;&#1086;&#1083;&#1100;&#1096;&#1091;&#1102; &#1095;&#1072;&#1089;&#1090;&#1100; &#1074;&#1074;&#1086;&#1076;&#1080;&#1084;&#1099;&#1093; &#1044;&#1077;&#1083;&#1100;&#1092;&#1080; &#1092;&#1080;&#1095; &#1080; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1080;&#1088;&#1091;&#1077;&#1090;&#1089;&#1103; &#1087;&#1086;&#1076;&#1086; &#1074;&#1089;&#1105; &#1085;&#1072; &#1089;&#1074;&#1077;&#1090;&#1077;, &#1074; &#1090;&#1086;&#1084; &#1095;&#1080;&#1089;&#1083;&#1077; &#1087;&#1086;&#1076; linux-x32, linux-x64 &#1080; native-android (&#1089; &#1087;&#1086;&#1084;&#1086;&#1097;&#1100;&#1102; <a href="http://www.crossfpc.com/" target="_blank">&#1101;&#1090;&#1086;&#1081; &#1096;&#1090;&#1091;&#1082;&#1080;</a> &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1103;&#1090;&#1086;&#1088; FPC &#1084;&#1086;&#1078;&#1085;&#1086; &#1074;&#1089;&#1090;&#1088;&#1086;&#1080;&#1090;&#1100; &#1074; &#1080;&#1085;&#1090;&#1077;&#1088;&#1092;&#1077;&#1081;&#1089; &#1076;&#1077;&#1083;&#1100;&#1092;&#1080;, &#1077;&#1089;&#1083;&#1080; &#1085;&#1077; &#1085;&#1088;&#1072;&#1074;&#1080;&#1090;&#1089;&#1103; Lazarus). &#1048; &#1077;&#1089;&#1090;&#1100; Oxygene, &#1082;&#1086;&#1090;&#1086;&#1088;&#1099;&#1081; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1080;&#1088;&#1091;&#1077;&#1090;&#1089;&#1103; &#1087;&#1086;&#1076; .NET, Android &#1080; iPhone, &#1080; &#1090;&#1086;&#1078;&#1077; &#1074;&#1074;&#1086;&#1076;&#1080;&#1090; &#1074; &#1103;&#1079;&#1099;&#1082; &#1084;&#1085;&#1086;&#1075;&#1086; &#1082;&#1088;&#1091;&#1090;&#1086;&#1075;&#1086;. (&#1048; &#1074; &#1085;&#1105;&#1084; &#1074;&#1084;&#1077;&#1089;&#1090;&#1086; VCL &#1080;&#1089;&#1087;&#1086;&#1083;&#1100;&#1079;&#1091;&#1102;&#1090;&#1089;&#1103; &#1085;&#1072;&#1090;&#1080;&#1074;&#1085;&#1099;&#1077; &#1092;&#1086;&#1088;&#1084;&#1099; &#1082;&#1072;&#1078;&#1076;&#1086;&#1081; &#1087;&#1083;&#1072;&#1090;&#1092;&#1086;&#1088;&#1084;&#1099;, &#1090;&#1080;&#1087;&#1072; Windows Forms).<br><br>&#1058;&#1086; &#1077;&#1089;&#1090;&#1100;, &#1074; &#1086;&#1073;&#1097;&#1077;&#1084;-&#1090;&#1086;, &#1087;&#1086;&#1082;&#1088;&#1099;&#1090;&#1072; &#1074;&#1089;&#1103; &#1084;&#1099;&#1089;&#1083;&#1080;&#1084;&#1072;&#1103; &#1088;&#1072;&#1079;&#1088;&#1072;&#1073;&#1086;&#1090;&#1082;&#1072; &#1076;&#1083;&#1103; &#1083;&#1086;&#1082;&#1072;&#1083;&#1100;&#1085;&#1099;&#1093; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1080;&#1088;&#1091;&#1077;&#1084;&#1099;&#1093; &#1103;&#1079;&#1099;&#1082;&#1086;&#1074;. &#1050;&#1088;&#1086;&#1084;&#1077; &#1080;&#1085;&#1090;&#1077;&#1088;&#1087;&#1088;&#1077;&#1090;&#1080;&#1088;&#1091;&#1077;&#1084;&#1099;&#1093; &#1103;&#1079;&#1099;&#1082;&#1086;&#1074;, &#1077;&#1076;&#1080;&#1085;&#1089;&#1090;&#1074;&#1077;&#1085;&#1085;&#1099;&#1081; &#1103;&#1079;&#1099;&#1082; &#1089; &#1090;&#1072;&#1082;&#1080;&#1084; &#1087;&#1086;&#1082;&#1088;&#1099;&#1090;&#1080;&#1077;&#1084; - &#1101;&#1090;&#1086; C/C++. &#1048; &#1082;&#1089;&#1090;&#1072;&#1090;&#1080;, &#1077;&#1089;&#1083;&#1080; &#1087;&#1086;&#1083;&#1100;&#1079;&#1086;&#1074;&#1072;&#1090;&#1100;&#1089;&#1103; &#1090;&#1086;&#1083;&#1100;&#1082;&#1086; &#1087;&#1072;&#1089;&#1082;&#1072;&#1083;&#1105;&#1084; &#1091;&#1088;&#1086;&#1074;&#1085;&#1103; Delphi 7, &#1089;&#1090;&#1072;&#1085;&#1076;&#1072;&#1088;&#1090;&#1085;&#1086;&#1081; &#1073;&#1080;&#1073;&#1083;&#1080;&#1086;&#1090;&#1077;&#1082;&#1086;&#1081; &#1074;&#1084;&#1077;&#1089;&#1090;&#1086; &#1074;&#1080;&#1085;&#1072;&#1087;&#1080;, &#1080; &#1086;&#1075;&#1088;&#1072;&#1085;&#1080;&#1095;&#1080;&#1090;&#1100;&#1089;&#1103; &#1082;&#1086;&#1085;&#1089;&#1086;&#1083;&#1100;&#1085;&#1099;&#1084; &#1080;&#1083;&#1080; &#1089;&#1077;&#1088;&#1074;&#1080;&#1089;&#1085;&#1099;&#1084; &#1087;&#1088;&#1080;&#1083;&#1086;&#1078;&#1077;&#1085;&#1080;&#1077;&#1084;, &#1090;&#1086; &#1087;&#1088;&#1086;&#1075;&#1088;&#1072;&#1084;&#1084;&#1091; &#1084;&#1086;&#1078;&#1085;&#1086; &#1073;&#1091;&#1076;&#1077;&#1090; &#1089;&#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1080;&#1090;&#1100; &#1085;&#1072; &#1083;&#1102;&#1073;&#1086;&#1084; &#1080;&#1079; &#1101;&#1090;&#1080;&#1093; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1103;&#1090;&#1086;&#1088;&#1086;&#1074;. &#1048;&#1085;&#1090;&#1077;&#1088;&#1077;&#1089;&#1085;&#1086;, &#1087;&#1088;&#1086;&#1073;&#1086;&#1074;&#1072;&#1083; &#1083;&#1080; &#1082;&#1090;&#1086;-&#1085;&#1080;&#1073;&#1091;&#1076;&#1100;?]]></description>
										<content:encoded><![CDATA[<p>Если считать, что паскаль вымирает, то вымирать он умудряется с огоньком. У нас есть Delphi, который при всех проблемах управления постоянно вводит крутые возможности в язык. Он компилируется под win-x32, win-x64 и маки. Есть FreePascal, которые поддерживает большую часть вводимых Дельфи фич и компилируется подо всё на свете, в том числе под linux-x32, linux-x64 и native-android (с помощью <a href="http://www.crossfpc.com/" >этой штуки</a> компилятор FPC можно встроить в интерфейс дельфи, если не нравится Lazarus). И есть Oxygene, который компилируется под .NET, Android и iPhone, и тоже вводит в язык много крутого. (И в нём вместо VCL используются нативные формы каждой платформы, типа Windows Forms).</p>
<p>То есть, в общем-то, покрыта вся мыслимая разработка для локальных компилируемых языков. Кроме интерпретируемых языков, единственный язык с таким покрытием &#8211; это C/C++. И кстати, если пользоваться только паскалём уровня Delphi 7, стандартной библиотекой вместо винапи, и ограничиться консольным или сервисным приложением, то программу можно будет скомпилить на любом из этих компиляторов. Интересно, пробовал ли кто-нибудь?</p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2013/02/14/%d0%bf%d1%80%d0%be-%d0%bf%d0%b0%d1%81%d0%ba%d0%b0%d0%bb%d1%8c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Tell me what I&#8217;m going to use it for</title>
		<link>http://boku.ru/2013/01/22/tell-me-what-im-going-to-use-it-for/</link>
					<comments>http://boku.ru/2013/01/22/tell-me-what-im-going-to-use-it-for/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Tue, 22 Jan 2013 10:45:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[In English @en]]></category>
		<guid isPermaLink="false">http://www.diary.ru/~himself/p184732380.htm</guid>

					<description><![CDATA[For those who didn't know, there's a new pascal-based compiler on a market for a while, and a pretty cool one at that. Enter RemObjects Oxygene.It's Visual Studio-based, compiles to .NET, Android Java and iPhone Cocoa, resembles Pascal and implements t...]]></description>
										<content:encoded><![CDATA[<p>For those who didn&#8217;t know, there&#8217;s a new pascal-based compiler on a market for a while, and a pretty cool one at that. Enter <a href="http://www.remobjects.com/oxygene/" >RemObjects Oxygene</a>.</p>
<p>It&#8217;s Visual Studio-based, compiles to .NET, Android Java and iPhone Cocoa, resembles Pascal and implements the majority of its cool features like generics. Parts of language are <a href="http://wiki.oxygenelanguage.com/en/Minor_Language_Differences_compared_to_Delphi" >redesigned</a>, some for better, some for worse.</p>
<p><b>Cool feature</b>. Even the main unit now has the interface/implementation sections.</p>
<pre><code>namespace Application1;
interface
implementation
begin
  Console.WriteLine("The magic happens here.");
end.</code></pre>
<p><b>Uncool feature</b>. <code>initialization</code>/<code>finalization</code> sections are no more. I guess you can kinda replace them with class constructors, but <i>they were so much better</i>.</p>
<p>Anyway.</p>
<p>The language is indeed pretty fresh, with support even for WinRT while Delphi has yet to convince Microsoft <a href="http://www.deltics.co.nz/blog/?p=1080#more-1080" >to let everyone else have a part of the cake</a>. <span class="offtop">Turns out, the only way to do native WinRT applications is through using Microsoft Visual C++ Runtime. Ha-ha, funny joke Microsoft, you.</span></p>
<p>So I thought about playing with it for a change.<br />
No, I&#8217;m not betraying Delphi <span class="offtop">just yet</span>. It&#8217;s still pretty cool, compiling to 64 bit and not being afraid of anything.</p>
<p>But sitting before the empty Oxygene project, I have found myself at loss at what to do.<br />
Okay, it runs. It compiles Hello World, alright.<br />
What next?</p>
<p>Turns out, when you encounter a new language, you have to have a few use cases for it. And since you usually don&#8217;t know what this langage <i>can</i> do, it&#8217;s better if someone suggests those for you.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2013/01/22/tell-me-what-im-going-to-use-it-for/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Inc(i)</title>
		<link>http://boku.ru/2013/01/04/inci/</link>
					<comments>http://boku.ru/2013/01/04/inci/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Fri, 04 Jan 2013 18:49:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<guid isPermaLink="false">http://www.diary.ru/~himself/p184197713.htm</guid>

					<description><![CDATA[&#1042;&#1089;&#1077; &#1079;&#1085;&#1072;&#1102;&#1090;, &#1095;&#1090;&#1086; &#1082;&#1086;&#1075;&#1076;&#1072; &#1087;&#1077;&#1088;&#1077;&#1073;&#1080;&#1088;&#1072;&#1077;&#1096;&#1100; null-terminated &#1089;&#1090;&#1088;&#1086;&#1082;&#1080;, &#1090;&#1086; &#1085;&#1091;&#1078;&#1085;&#1086; &#1086;&#1089;&#1090;&#1072;&#1085;&#1072;&#1074;&#1083;&#1080;&#1074;&#1072;&#1090;&#1100;&#1089;&#1103; &#1087;&#1086; &#1085;&#1091;&#1083;&#1102;:<br><code><pre>while pc^&#60;&#62;#00 do Inc(pc); //&#1080;&#1097;&#1077;&#1084; &#1082;&#1086;&#1085;&#1077;&#1094; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080;</pre></code>&#1042;&#1089;&#1077; &#1079;&#1085;&#1072;&#1102;&#1090;, &#1095;&#1090;&#1086; &#1082;&#1086;&#1075;&#1076;&#1072; &#1087;&#1077;&#1088;&#1077;&#1073;&#1080;&#1088;&#1072;&#1077;&#1096;&#1100; &#1076;&#1077;&#1083;&#1100;&#1092;&#1080;&#1081;&#1089;&#1082;&#1080;&#1077; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080;, &#1085;&#1091;&#1078;&#1085;&#1086; &#1086;&#1089;&#1090;&#1072;&#1085;&#1072;&#1074;&#1083;&#1080;&#1074;&#1072;&#1090;&#1100;&#1089;&#1103;, &#1082;&#1086;&#1075;&#1076;&#1072; &#1080;&#1085;&#1076;&#1077;&#1082;&#1089; &#1087;&#1088;&#1077;&#1074;&#1099;&#1089;&#1080;&#1090; &#1076;&#1083;&#1080;&#1085;&#1091; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080;:<br><code><pre>while (i&#60;Length(s)) and (s[i]=' ') do Inc(i); //&#1087;&#1088;&#1086;&#1087;&#1091;&#1089;&#1082;&#1072;&#1077;&#1084; &#1087;&#1088;&#1086;&#1073;&#1077;&#1083;&#1099;</pre></code>&#1042;&#1089;&#1077; &#1079;&#1085;&#1072;&#1102;&#1090;, &#1095;&#1090;&#1086; &#1091; &#1076;&#1077;&#1083;&#1100;&#1092;&#1080;&#1081;&#1089;&#1082;&#1080;&#1093; &#1089;&#1090;&#1088;&#1086;&#1082; &#1074; &#1082;&#1086;&#1085;&#1094;&#1077; &#1074;&#1089;&#1105; &#1088;&#1072;&#1074;&#1085;&#1086; &#1085;&#1086;&#1083;&#1100;.<br><code><pre> 74 00 65 00 73 00 74 00 <b>00 00</b></pre></code>&#1053;&#1086; &#1085;&#1077; &#1074;&#1089;&#1077;&#1084; &#1080; &#1085;&#1077; &#1089;&#1088;&#1072;&#1079;&#1091; &#1087;&#1088;&#1080;&#1093;&#1086;&#1076;&#1080;&#1090; &#1074; &#1075;&#1086;&#1083;&#1086;&#1074;&#1091;, &#1095;&#1090;&#1086; &#1076;&#1083;&#1080;&#1085;&#1091; &#1076;&#1077;&#1083;&#1100;&#1092;&#1080;&#1081;&#1089;&#1082;&#1086;&#1081; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080; &#1090;&#1086;&#1078;&#1077; &#1095;&#1072;&#1089;&#1090;&#1086; &#1084;&#1086;&#1078;&#1085;&#1086; &#1085;&#1077; &#1087;&#1088;&#1086;&#1074;&#1077;&#1088;&#1103;&#1090;&#1100;!<br>&#1042;&#1090;&#1086;&#1088;&#1086;&#1081; &#1087;&#1088;&#1080;&#1084;&#1077;&#1088; &#1084;&#1086;&#1078;&#1085;&#1086; &#1079;&#1072;&#1087;&#1080;&#1089;&#1072;&#1090;&#1100; &#1090;&#1072;&#1082;:<br><code><pre>while s[i]=' ' do Inc(i); //&#1087;&#1088;&#1086;&#1087;&#1091;&#1089;&#1082;&#1072;&#1077;&#1084; &#1087;&#1088;&#1086;&#1073;&#1077;&#1083;&#1099;</pre></code>&#1042; &#1082;&#1086;&#1085;&#1094;&#1077; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080; &#1085;&#1086;&#1083;&#1100;, &#1072; &#1085;&#1086;&#1083;&#1100; - &#1101;&#1090;&#1086; &#1085;&#1077; &#1087;&#1088;&#1086;&#1073;&#1077;&#1083;, &#1087;&#1086;&#1101;&#1090;&#1086;&#1084;&#1091; &#1094;&#1080;&#1082;&#1083; &#1089;&#1072;&#1084; &#1089;&#1086;&#1073;&#1086;&#1081; &#1087;&#1088;&#1077;&#1088;&#1074;&#1105;&#1090;&#1089;&#1103;.<br><br>&#1043;&#1076;&#1077; &#1085;&#1072;&#1076;&#1086; &#1073;&#1099;&#1090;&#1100; &#1086;&#1089;&#1090;&#1086;&#1088;&#1086;&#1078;&#1085;&#1099;&#1084; - &#1090;&#1072;&#1082; &#1101;&#1090;&#1086; &#1087;&#1088;&#1080; &#1087;&#1088;&#1086;&#1084;&#1086;&#1090;&#1082;&#1077; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080; &#1085;&#1072;&#1079;&#1072;&#1076;. &#1042; &#1085;&#1072;&#1095;&#1072;&#1083;&#1077; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080; &#1085;&#1091;&#1083;&#1103; &#1085;&#1077;&#1090;:<br><code><pre>while (i&#62;0) and (s[i]=' ') do Dec(i); //&#1087;&#1088;&#1086;&#1087;&#1091;&#1089;&#1082;&#1072;&#1077;&#1084; &#1087;&#1088;&#1086;&#1073;&#1077;&#1083;&#1099; &#1074; &#1086;&#1073;&#1088;&#1072;&#1090;&#1085;&#1091;&#1102; &#1089;&#1090;&#1086;&#1088;&#1086;&#1085;&#1091;</pre></code>
]]></description>
										<content:encoded><![CDATA[<p>Все знают, что когда перебираешь null-terminated строки, то нужно останавливаться по нулю:<br />
<code></p>
<pre>while pc^&lt;&gt;#00 do Inc(pc); //ищем конец строки</pre>
<p></code>Все знают, что когда перебираешь дельфийские строки, нужно останавливаться, когда индекс превысит длину строки:<br />
<code></p>
<pre>while (i&lt;Length(s)) and (s[i]=' ') do Inc(i); //пропускаем пробелы</pre>
<p></code>Все знают, что у дельфийских строк в конце всё равно ноль.<br />
<code></p>
<pre> 74 00 65 00 73 00 74 00 <b>00 00</b></pre>
<p></code>Но не всем и не сразу приходит в голову, что длину дельфийской строки тоже часто можно не проверять!<br />
Второй пример можно записать так:<br />
<code></p>
<pre>while s[i]=' ' do Inc(i); //пропускаем пробелы</pre>
<p></code>В конце строки ноль, а ноль &#8211; это не пробел, поэтому цикл сам собой прервётся.</p>
<p>Где надо быть осторожным &#8211; так это при промотке строки назад. В начале строки нуля нет:<br />
<code></p>
<pre>while (i&gt;0) and (s[i]=' ') do Dec(i); //пропускаем пробелы в обратную сторону</pre>
<p></code></p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2013/01/04/inci/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>type и class</title>
		<link>http://boku.ru/2012/12/30/type-%d0%b8-class/</link>
					<comments>http://boku.ru/2012/12/30/type-%d0%b8-class/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Sun, 30 Dec 2012 09:36:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<guid isPermaLink="false">http://www.diary.ru/~himself/p184040698.htm</guid>

					<description><![CDATA[&#1042; Delphi &#1084;&#1086;&#1078;&#1085;&#1086; &#1085;&#1072;&#1087;&#1080;&#1089;&#1072;&#1090;&#1100;:<br><code><pre>type HexString = string;</pre></code>&#1058;&#1072;&#1082; &#1084;&#1099; &#1086;&#1090;&#1084;&#1077;&#1090;&#1080;&#1084; &#1089;&#1087;&#1077;&#1094;&#1080;&#1072;&#1083;&#1100;&#1085;&#1099;&#1081; &#1090;&#1080;&#1087; &#1089;&#1090;&#1088;&#1086;&#1082;, &#1082;&#1086;&#1090;&#1086;&#1088;&#1099;&#1081; &#1093;&#1088;&#1072;&#1085;&#1080;&#1090; &#1074; &#1089;&#1077;&#1073;&#1077; hex. &#1053;&#1086; &#1076;&#1083;&#1103; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1103;&#1090;&#1086;&#1088;&#1072; &#1086;&#1085;&#1080; &#1085;&#1080;&#1095;&#1077;&#1084; &#1085;&#1077; &#1086;&#1090;&#1083;&#1080;&#1095;&#1072;&#1102;&#1090;&#1089;&#1103; &#1086;&#1090; &#1086;&#1073;&#1099;&#1095;&#1085;&#1099;&#1093;. &#1042;&#1086;&#1090; &#1101;&#1090;&#1086; &#1089;&#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1080;&#1088;&#1091;&#1077;&#1090;&#1089;&#1103; &#1085;&#1086;&#1088;&#1084;&#1072;&#1083;&#1100;&#1085;&#1086;:<br><code><pre>var a: HexString;<br>  b: string;<br>begin<br>  a := b;<br>end;</pre></code>&#1063;&#1090;&#1086;, &#1077;&#1089;&#1083;&#1080; &#1084;&#1099; &#1085;&#1077; &#1093;&#1086;&#1090;&#1080;&#1084; &#1088;&#1072;&#1079;&#1088;&#1077;&#1096;&#1072;&#1090;&#1100; &#1090;&#1072;&#1082;&#1086;&#1077; &#1082;&#1086;&#1087;&#1080;&#1088;&#1086;&#1074;&#1072;&#1085;&#1080;&#1077;? (&#1040; &#1086;&#1073;&#1099;&#1095;&#1085;&#1086; &#1084;&#1099; &#1076;&#1086;&#1083;&#1078;&#1085;&#1099; &#1085;&#1077; &#1093;&#1086;&#1090;&#1077;&#1090;&#1100;! &#1056;&#1072;&#1079;&#1085;&#1099;&#1077; &#1087;&#1086; &#1089;&#1084;&#1099;&#1089;&#1083;&#1091; &#1074;&#1077;&#1097;&#1080; &#1085;&#1077;&#1083;&#1100;&#1079;&#1103; &#1087;&#1088;&#1080;&#1089;&#1074;&#1072;&#1080;&#1074;&#1072;&#1090;&#1100;, &#1101;&#1090;&#1086; &#1086;&#1087;&#1072;&#1089;&#1085;&#1086;). &#1050;&#1086;&#1084;&#1087;&#1080;&#1083;&#1103;&#1090;&#1086;&#1088; &#1084;&#1086;&#1078;&#1085;&#1086; &#1087;&#1086;&#1087;&#1088;&#1086;&#1089;&#1080;&#1090;&#1100; &#1089;&#1086;&#1079;&#1076;&#1072;&#1090;&#1100; "&#1085;&#1077;&#1079;&#1072;&#1074;&#1080;&#1089;&#1080;&#1084;&#1099;&#1081; &#1090;&#1080;&#1087;":<br><code><pre>type HexString = <b>type</b> string;</pre></code>&#1058;&#1077;&#1087;&#1077;&#1088;&#1100; &#1089;&#1090;&#1088;&#1086;&#1082;&#1091; &#1090;&#1080;&#1087;&#1072; HexString &#1085;&#1077;&#1083;&#1100;&#1079;&#1103; &#1087;&#1088;&#1080;&#1089;&#1074;&#1086;&#1080;&#1090;&#1100; &#1089;&#1090;&#1088;&#1086;&#1082;&#1077; &#1090;&#1080;&#1087;&#1072; string, &#1080; &#1085;&#1072;&#1086;&#1073;&#1086;&#1088;&#1086;&#1090;.<br><br>&#1055;&#1086;&#1093;&#1086;&#1078;&#1080;&#1081; &#1087;&#1088;&#1080;&#1105;&#1084; &#1088;&#1072;&#1073;&#1086;&#1090;&#1072;&#1077;&#1090; &#1089; &#1082;&#1083;&#1072;&#1089;&#1089;&#1072;&#1084;&#1080;, &#1090;&#1086;&#1083;&#1100;&#1082;&#1086; &#1095;&#1091;&#1090;&#1100; &#1080;&#1085;&#1072;&#1095;&#1077;.<br><code><pre>type<br>  HexStringList = TStringList; //&#1084;&#1086;&#1078;&#1085;&#1086; &#1087;&#1088;&#1080;&#1089;&#1074;&#1072;&#1080;&#1074;&#1072;&#1090;&#1100; HexStringList -&#62; StringList &#1080; &#1086;&#1073;&#1088;&#1072;&#1090;&#1085;&#1086;!<br>  HexStringList = <b>class</b>(TStringList); //&#1084;&#1086;&#1078;&#1085;&#1086; &#1087;&#1088;&#1080;&#1089;&#1074;&#1072;&#1080;&#1074;&#1072;&#1090;&#1100; &#1090;&#1086;&#1083;&#1100;&#1082;&#1086; HexStringList -&#62; StringList, &#1085;&#1086; &#1085;&#1077; &#1086;&#1073;&#1088;&#1072;&#1090;&#1085;&#1086;!</pre></code>&#1050;&#1083;&#1072;&#1089;&#1089;&#1099;, &#1074; &#1086;&#1090;&#1083;&#1080;&#1095;&#1080;&#1077; &#1086;&#1090; &#1087;&#1088;&#1086;&#1089;&#1090;&#1099;&#1093; &#1090;&#1080;&#1087;&#1086;&#1074;, &#1087;&#1086;&#1076;&#1076;&#1077;&#1088;&#1078;&#1080;&#1074;&#1072;&#1102;&#1090; &#1085;&#1072;&#1089;&#1083;&#1077;&#1076;&#1086;&#1074;&#1072;&#1085;&#1080;&#1077;. &#1041;&#1086;&#1083;&#1077;&#1077; "&#1095;&#1072;&#1089;&#1090;&#1085;&#1099;&#1081;" &#1082;&#1083;&#1072;&#1089;&#1089; &#1084;&#1086;&#1078;&#1085;&#1086; &#1087;&#1086;&#1083;&#1086;&#1078;&#1080;&#1090;&#1100; &#1074; &#1087;&#1077;&#1088;&#1077;&#1084;&#1077;&#1085;&#1085;&#1091;&#1102; &#1073;&#1086;&#1083;&#1077;&#1077; &#1086;&#1073;&#1097;&#1077;&#1075;&#1086;, &#1085;&#1086; &#1085;&#1077; &#1085;&#1072;&#1086;&#1073;&#1086;&#1088;&#1086;&#1090;. &#1045;&#1089;&#1083;&#1080; &#1084;&#1099; &#1086;&#1073;&#1098;&#1103;&#1074;&#1083;&#1103;&#1077;&#1084; &#1090;&#1080;&#1087; &#1073;&#1077;&#1079; "<code>class</code>", &#1090;&#1086; &#1084;&#1099; &#1087;&#1088;&#1086;&#1089;&#1090;&#1086; &#1089;&#1086;&#1079;&#1076;&#1072;&#1105;&#1084; &#1076;&#1083;&#1103; &#1085;&#1077;&#1075;&#1086; &#1076;&#1088;&#1091;&#1075;&#1086;&#1077; &#1080;&#1084;&#1103;: &#1086;&#1073;&#1072; &#1090;&#1080;&#1087;&#1072; &#1085;&#1072; &#1089;&#1072;&#1084;&#1086;&#1084; &#1076;&#1077;&#1083;&#1077; &#1086;&#1076;&#1085;&#1086; &#1080; &#1090;&#1086; &#1078;&#1077;. &#1040; &#1089; &#1087;&#1086;&#1084;&#1086;&#1097;&#1100;&#1102; "<code>class(TStringList)</code>" &#1084;&#1099; &#1075;&#1086;&#1074;&#1086;&#1088;&#1080;&#1084; &#1082;&#1086;&#1084;&#1087;&#1080;&#1083;&#1103;&#1090;&#1086;&#1088;&#1091; "HexStringList - &#1101;&#1090;&#1086; <i>&#1095;&#1072;&#1089;&#1090;&#1085;&#1099;&#1081; &#1089;&#1083;&#1091;&#1095;&#1072;&#1081;</i> StringList, &#1086;&#1085; &#1086;&#1090; &#1085;&#1077;&#1075;&#1086; &#1085;&#1072;&#1089;&#1083;&#1077;&#1076;&#1091;&#1077;&#1090;".<br><br>&#1053;&#1086; &#1095;&#1090;&#1086;, &#1077;&#1089;&#1083;&#1080; &#1084;&#1099; &#1085;&#1072;&#1087;&#1080;&#1096;&#1077;&#1084; &#1090;&#1072;&#1082;?<br><code><pre>type HexStringList = <b>type</b> TStringList;</pre></code>&#1048;&#1083;&#1080; &#1090;&#1072;&#1082;?<br><code><pre>type HexStringList = <b>type class</b>(TStringList);</pre></code>&#1054;&#1090;&#1074;&#1077;&#1090;&#1099; &#1085;&#1072; &#1101;&#1090;&#1086; &#1074; &#1089;&#1083;&#1077;&#1076;&#1091;&#1102;&#1097;&#1080;&#1081; &#1088;&#1072;&#1079;!#1077; hex. ]]></description>
										<content:encoded><![CDATA[<p>В Delphi можно написать:<br />
<code></p>
<pre>type HexString = string;</pre>
<p></code>Так мы отметим специальный тип строк, который хранит в себе hex. Но для компилятора они ничем не отличаются от обычных. Вот это скомпилируется нормально:<br />
<code></p>
<pre>var a: HexString;
  b: string;
begin
  a := b;
end;</pre>
<p></code>Что, если мы не хотим разрешать такое копирование? (А обычно мы должны не хотеть! Разные по смыслу вещи нельзя присваивать, это опасно). Компилятор можно попросить создать &#8220;независимый тип&#8221;:<br />
<code></p>
<pre>type HexString = <b>type</b> string;</pre>
<p></code>Теперь строку типа HexString нельзя присвоить строке типа string, и наоборот.</p>
<p>Похожий приём работает с классами, только чуть иначе.<br />
<code></p>
<pre>type
  HexStringList = TStringList; //можно присваивать HexStringList -&gt; StringList и обратно!
  HexStringList = <b>class</b>(TStringList); //можно присваивать только HexStringList -&gt; StringList, но не обратно!</pre>
<p></code>Классы, в отличие от простых типов, поддерживают наследование. Более &#8220;частный&#8221; класс можно положить в переменную более общего, но не наоборот. Если мы объявляем тип без &#8220;<code>class</code>&#8220;, то мы просто создаём для него другое имя: оба типа на самом деле одно и то же. А с помощью &#8220;<code>class(TStringList)</code>&#8221; мы говорим компилятору &#8220;HexStringList &#8211; это <i>частный случай</i> StringList, он от него наследует&#8221;.</p>
<p>Но что, если мы напишем так?<br />
<code></p>
<pre>type HexStringList = <b>type</b> TStringList;</pre>
<p></code>Или так?<br />
<code></p>
<pre>type HexStringList = <b>type class</b>(TStringList);</pre>
<p></code>Ответы на это в следующий раз!</p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2012/12/30/type-%d0%b8-class/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Консты нереально круты</title>
		<link>http://boku.ru/2012/12/07/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%8b-%d0%bd%d0%b5%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-%d0%ba%d1%80%d1%83%d1%82%d1%8b/</link>
					<comments>http://boku.ru/2012/12/07/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%8b-%d0%bd%d0%b5%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-%d0%ba%d1%80%d1%83%d1%82%d1%8b/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Fri, 07 Dec 2012 18:45:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<guid isPermaLink="false">http://www.diary.ru/~himself/p183300023.htm</guid>

					<description><![CDATA[Да, я понимаю, что тут никто не пишет на дельфи, но раз уж я иногда что-то пишу о ней, то позвольте мне.В дельфи есть элемент языка, которым вс...]]></description>
										<content:encoded><![CDATA[<p>Да, я понимаю, что тут никто не пишет на дельфи, но раз уж я иногда что-то пишу о ней, то позвольте мне.</p>
<p>В дельфи есть элемент языка, которым все пренебрегают. Очень крутой. Это атрибут входного параметра <b>const</b>.<br />
Вместо:<br />
<code>function IsStringAbrakadabra(s:string): boolean</code><br />
Получится:<br />
<code>function IsStringAbrakadabra(const s:string): boolean</code></p>
<p>Зачем?<br />
Строки в Дельфи ведут учёт ссылок. Каждое присваивание увеличивает счётчик на 1. Каждое зануление &#8211; уменьшает его. Поэтому любая функция, которая получает строки, преобразуется компилятором в следующую:</p>
<pre><code>UStrLAsg(s); //увеличить счётчик ссылок
try
  //сама функция
finally
  UStrLClr(s); //уменьшить счётчик ссылок
end;</code></pre>
<p>Два лишних вызова! И фрейм try..finally (это очень дорогая конструкция). Эта обёртка легко может тратить больше времени, чем сама ваша функция! Скомпилите и посмотрите в ассемблер &#8211; инлайнить такую дуру тоже пропадает всякая выгода.</p>
<p>На помощь спешит модификатор const! Он говорит компилятору, что вы клянётесь героиней любимого мультика не трогать полученной строки. Тогда можно учёт ссылок не вести, и фрейм try..finally тоже не нужен. Вместо 60 ассемблерных инструкций ваша функция внезапно компилируется в шесть!</p>
<p>Но это ещё не всё.<br />
Мало добавлять const к строковым параметрам. Строки могут передаваться неявно. Функция, которая получает структуру со строкой внутри, <i>тоже требует учёта ссылок и фрейма try..finally</i>. Даже хуже: вместо прямолинейного UStrLAsg будет вызван AddRefRecord, который с помощью некоего подобия рефлекшна изучает вашу структуру и решает, каким полям нужен какой учёт ссылок. И так в каждой функции!<br />
<span class="offtop">Дельфи не глупая, и если структуре совсем не нужен учёт ссылок, она поймёт это при компиляции, и фрейм не вставит. Но когда хоть одно поле требует учёта, вы получите пенальти в размере полного разбора всей структуры дважды.</span></p>
<p>Поэтому ставьте const везде, где можно. Ставьте const всему, что передаёте на копирование во всевозможные &#8220;SetSomething&#8221; или &#8220;InitSomething&#8221;. В крайнем случае он будет просто подсказкой читающему код.</p>
<p><b>Ещё очень важная информация:</b> <a href="http://www.micro-isv.asia/2008/10/needless-string-checks-with-ensureunicodestring/" >отключайте &#8220;String format checking&#8221;</a> в настройках компиляции. Всегда. Сразу же. Эту опцию следовало бы назвать &#8220;замедлить в три раза все операции со строками, для того, чтобы спрятать от вас чудовищные баги в вашем коде&#8221;.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2012/12/07/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%8b-%d0%bd%d0%b5%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-%d0%ba%d1%80%d1%83%d1%82%d1%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Это просто праздник какой-то</title>
		<link>http://boku.ru/2012/11/28/%d1%8d%d1%82%d0%be-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be-%d0%bf%d1%80%d0%b0%d0%b7%d0%b4%d0%bd%d0%b8%d0%ba-%d0%ba%d0%b0%d0%ba%d0%be%d0%b9-%d1%82%d0%be/</link>
					<comments>http://boku.ru/2012/11/28/%d1%8d%d1%82%d0%be-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be-%d0%bf%d1%80%d0%b0%d0%b7%d0%b4%d0%bd%d0%b8%d0%ba-%d0%ba%d0%b0%d0%ba%d0%be%d0%b9-%d1%82%d0%be/#respond</comments>
		
		<dc:creator><![CDATA[himself]]></dc:creator>
		<pubDate>Wed, 28 Nov 2012 00:41:00 +0000</pubDate>
				<category><![CDATA[Delphi]]></category>
		<guid isPermaLink="false">http://www.diary.ru/~himself/p182994166.htm</guid>

					<description><![CDATA[if AnsiCompareStr(uppercase(value),uppercase(s))&#60;0 then r:=c elseif AnsiCompareStr(uppercase(value),uppercase(s))&#62;0 then l:=c+1 elseif AnsiCompareStr(uppercase(value),uppercase(s))=0 then r:=c;Мало того, что "&#60;=" разбито на...]]></description>
										<content:encoded><![CDATA[<p><code>if AnsiCompareStr(uppercase(value),uppercase(s))&lt;0 then r:=c else<br />
if AnsiCompareStr(uppercase(value),uppercase(s))&gt;0 then l:=c+1 else<br />
if AnsiCompareStr(uppercase(value),uppercase(s))=0 then r:=c;</code></p>
<p>Мало того, что &#8220;&lt;=&#8221; разбито на &#8220;&lt;&#8221; и &#8220;=&#8221; с одинаковым исходом, так тут вообще достаточно одной проверки:</p>
<p><code>if AnsiCompareStr(uppercase(value),uppercase(s))&lt;=0 then r:=c else l:=c+1;</code></p>
<p><b>UPD</b>. Я в этот пост буду складывать все такие примеры!</p>
<pre><code>if (doall) then
begin
  if not doall then
  begin</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>http://boku.ru/2012/11/28/%d1%8d%d1%82%d0%be-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be-%d0%bf%d1%80%d0%b0%d0%b7%d0%b4%d0%bd%d0%b8%d0%ba-%d0%ba%d0%b0%d0%ba%d0%be%d0%b9-%d1%82%d0%be/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
