<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6265149071939082693</id><updated>2012-02-17T05:18:05.981+02:00</updated><category term='modular architecture'/><category term='dynamic binding'/><category term='people'/><category term='OSGi'/><category term='git'/><category term='books'/><category term='patterns'/><category term='compilers'/><category term='languages'/><category term='production'/><category term='engine'/><category term='assets'/><category term='version control'/><category term='Android'/><category term='binary encapsulation'/><category term='D'/><category term='perforce'/><category term='life'/><title type='text'>Core Architecture</title><subtitle type='html'>All about large-scale development and software architecture</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-206018936905853884</id><published>2011-10-02T16:17:00.001+03:00</published><updated>2011-10-02T16:18:28.934+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='production'/><category scheme='http://www.blogger.com/atom/ns#' term='perforce'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='assets'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><title type='text'>Generalizing version control systems</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Continuing on the version control system &lt;strike&gt;hatred&lt;/strike&gt; criticism topic&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;When VCS does not fit&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="restofpost"&gt;&lt;div style="text-align: justify;"&gt;On GDCE 2011 I've attended a talk of a guy from CCP Games (&lt;a href="http://www.gdcvault.com/play/1014875/Addressing-Human-Scalability-Through-Multi"&gt;"Addressing Human Scalability Through Multi-User Editing Using Revision Databases" by John Rittenhouse&lt;/a&gt;) where he told about how they addressed the problem of the artists editing their levels \ galaxies. We in Crytek have relatively small levels, so when artist wants to make some modifications to it he just locks it for exclusive edit in Perforce.&amp;nbsp;Their levels are huge and do not have a distinctive partitioning.&amp;nbsp;In CCP, it is common for multiple artists to make changes to the same level simultaneously, so exclusive locks are unacceptable.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Their solution was to move out from files in Perforce and store levels in MySQL database. To stop artists from messing each-others work they have implemented the object-level locking, so, for example, if one artist moves a box on a level the corresponding row in DB will marked as locked. In level editor other artists will see that this object is being worked on and will not be able to change it. They have traded the file-level atomicity of Perforce for row-level in MySQL, well I guess you've got the idea.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Anyway, the most interesting takeaway from the talk was how they have struggled with this technology to fit it into their production pipeline. First of all, the described approach is similar to working on code without revision control at all, so they have added support for changelists, submits and reverts from the beginning. Then they had a real headache adding branching, but they have only supported a simplified "promotional branching" model where there is only one flow of changes. But their production were moving towards the "mainline branching" (see the slides) so their system could not keep up with this. And, as I understood, at the time of talk this issue was not solved yet.&amp;nbsp;Basically by making this move they have condemned themselves to implement the analogue of Perforce on top of MySQL which is a damn hard thing to do.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;VCS hell&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In the previous post I've expressed my doubts about having separate version control systems for code and assets, related to how it affects the atomicity of changes and consistency of changelists.&amp;nbsp;Essentially&amp;nbsp;CCP added one more VCS for the level data. This is insane.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I'm not saying that CCP made a wrong move by doing this, in fact I can't think of any simple alternative. But having several VCS is a dead end. In fact CCP guys are aware of this, and, talking to a&amp;nbsp;colleague of mine, mentioned that they had thoughts about using actually putting all their code into MySQL to use it as single VCS.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;Solution (?)&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So above is one example of requirements that can't be reasonably fulfilled by any of the existing version control system, but I bet it is not the only one of its kind. As an architect (well I like to think of myself as one) when making some,&amp;nbsp;especially spontaneous,&amp;nbsp;decision I always question it from multiple sides "Why this is best?", "How will it work with X?", "How can it be generalized?".&amp;nbsp;And related to contemporary VCS following question always comes to my mind "Why do they have to operate on files?".&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Choosing a file as the unit of atomicity was probably one of those spontaneous&amp;nbsp;decisions&amp;nbsp;made when the first VCS was born, it is just a legacy. I want to be able to customize the behaviour of VCS, want to be able to change the atomicity unit any way I need, but keep the changelists, submits, reverts and branching untouched. Leaving the file as a primary atomicity unit (I can live with that :) why not to add handlers for a specific file types which will know which sub-units it consists of, how to diff and merge them etc? Lots of opportunities are opened this way, for example you can implement a handler for a video file, allowing you to edit each frame as a bitmap image, checkout separate tracks from a music pack, lock a single box on the level at last. You can go even more crazy with&amp;nbsp;hierarchical atomicity levels: basic level is a directory (you merge it by choosing which files to keep), next level is file (you merge them like you do this now), deeper levels are your custom handlers like area on level, which in its turn breaks down to objects.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Sadly, this becomes a tradition that each time I&amp;nbsp;analyse some technology&amp;nbsp;the conclusion is mostly "there's no such thing yet - write it yourself". Adding version control to my TODO list.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-206018936905853884?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/206018936905853884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2011/10/generalizing-version-control-systems.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/206018936905853884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/206018936905853884'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2011/10/generalizing-version-control-systems.html' title='Generalizing version control systems'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-8232093305447446342</id><published>2011-09-29T16:03:00.000+03:00</published><updated>2011-09-29T20:35:12.324+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='production'/><category scheme='http://www.blogger.com/atom/ns#' term='perforce'/><category scheme='http://www.blogger.com/atom/ns#' term='assets'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Git vs. Perforce from game development viewpoint</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Recently been wondering about would how our infrastructure would've looked like if we were using Git instead of Perforce as version control system. So here's the summary:&lt;br /&gt;&lt;div class="restofpost"&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;&lt;strike&gt;Assets &lt;/strike&gt;&amp;nbsp;Version control for the real world&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;We store all of our assets in Perforce. Can git handle it? No.&lt;br /&gt;Many say that Git was created for different purposes. Indeed,&amp;nbsp;distributed&amp;nbsp;nature and the conceptual model that require rehashing of local files on most operations does not suite for big files at all. But I do not assess Git and Perforce for the 'things they&amp;nbsp;meant&amp;nbsp;to be used for', I am looking at how they satisfy my needs, and how they can be used in real projects. If you were 'making it for other purpose' and it does not&amp;nbsp;satisfy&amp;nbsp;common needs, maybe you were making the wrong tool.&lt;br /&gt;I think of a VCS as a heart of a company. It is not just code or just assets, &lt;b&gt;everything &lt;/b&gt;should be there. If artifact is not in version control - it does not exist. Every tool, script you write, every configuration file, everything should be backed up and (preferably) automatically syncing with VCS. It's convenient, it protects you from cases when machine fails and important scripts are lost, it simplifies understanding of tools and processes as you do not need to access the specific machine and reverse all the file dependencies to find out which configs, scripts etc. are actually used.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Assets (cont.)&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;Back to the topic, Git can't handle big files, what can we do about it? Often mentioned the approach with using separate VCS for code and assets. But one of important things VCS gives us is the consistency of the project. By consistency I mean the ability to sync Main to ANY changelist number, build it, and start the application. All changes ideally should be &lt;b&gt;atomic &lt;/b&gt;and leave project in a working state. This also means that when we submit a new feature to Main this have to be done in single changelist, &lt;b&gt;both code and data&lt;/b&gt;. How do you achieve consistency using multiple VCS when there is always a state when either data or code is out-of-sync? It would be interesting to hear some success stories about setup like this.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;Clientspecs&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;We use a lot of Perforce clientspec magic in our infrastructure. Automated builds, resource compilers, stress-testing, submit checkers etc. All those tools designed to operate on some subset of depot, sync the data, perform some operation, and submit the result. Clientspecs allow to specify which portions of depot to get and where to place them.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;How do you do something like that in Git? You surely don't want to clone the whole repository on every server. Event if it is vanilla source-code-only repository which is relatively small, I don't want to fetch things I do not need! Cloning with zero-depth history will save some space, but it is not a full solution.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;Advanced Clientspecs&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Some of the tools use complex mappings to compose the completely custom view of depot. For example stress testing system can operate on any of the feature branches we have, so on start it generates clientspec for specified branch, that maps all needed binaries and configuration files to the server. It maps all stress-testing scenarios and configs from 'Main' overriding with branch-specific configs if they are present (using '+' in clientspec). Pretty complex.&lt;br /&gt;You can't have two branches opened in Git&amp;nbsp;simultaneously, so in would require branching all configs from Main which is probably not a big deal. But you still unable to customize the layout of things. This can be a serious issue when you bind you version control with 3rd party tools, and probably will require symbolic links twiddling.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;Locks&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Locks are another interesting topic. In distributed version control you just don't have them. Now imagine having several designers tweaking the weapon parameters, or developers editing the localization files. Even if those files are in text format, such tools as Excel put huge amount of meta data in it, so it is practically becomes unmergeable. Our Perforce is configured&amp;nbsp;to lock such file types for exclusive editing.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;&lt;i&gt;Permissions&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;As I said earlier, I'm thinking of VCS as one of the central systems in the company, not the developers' toy only. When you have project planning docs, agreements, publisher SDKs etc. checked in to VCS the access control is&amp;nbsp;crucial.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But hey, even if you take the vanilla case for git (source code in repo only) how will you organize the stabilization process? Git manages permissions only on repository basis, so you would have to manage permission on push-pull level between Stabilization, Main, and Release repositories.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Decentralized!&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;i&gt;Git is decentralized! Haha! Eat this Perforce!&lt;/i&gt; ...you may say.&lt;br /&gt;Yes, it is, so what? Take the most popular hosting for Git - Github, take the &lt;a href="http://nvie.com/posts/a-successful-git-branching-model/"&gt;branching models for Git&lt;/a&gt;, all they do is centralize it.&amp;nbsp;Of course you can do a peer-to-peer exchange, but do you really need it?&amp;nbsp;Most people just fork the existing projects and working on them, again, as in centralized VCM.&lt;br /&gt;So why do you need to throw away all the benefits of centralization like simple solution for big files, changes tracking, shelves etc.? Yes, I will not be able to read the whole history of the project while flying in the plane, but hey, I prefer to read a book while flying anyway. And I feel safer when I know that whole project can't be stolen that easily :)&lt;br /&gt;&lt;br /&gt;Still have some thoughts left, but I'll leave them for the next post.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-8232093305447446342?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/8232093305447446342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2011/09/git-vs-perforce-from-game-development.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8232093305447446342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8232093305447446342'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2011/09/git-vs-perforce-from-game-development.html' title='Git vs. Perforce from game development viewpoint'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-9001201556212702743</id><published>2010-10-16T21:13:00.005+03:00</published><updated>2011-10-02T16:44:09.963+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compilers'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic binding'/><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='languages'/><title type='text'>Explicit class import</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;In this post I want to describe a small step every language should take on its way to modularity. I will describe the basic idea and applications of explicit class import, how this feature (implicitly) works in Java and the ways of implementing this vital feature in C++-like languages.&lt;/div&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;Here's what brought me to all this thoughts. I'm not a Java person in any way, but I was reading a book about OSGi and speciffically about how it treats the classpath and class loaders. Basically class path is a root namespace. When the Jar is loaded, its classes are merged into the class path, allowing you to instantiate them. In pure Java it often creates a class path hell. Class names from different Jars can collide when being added to class path. OSGi solves this problem&amp;nbsp;elegantly&amp;nbsp;at the bundle resolution stage by manipulating class paths and creating isolated environments for each bundle.&lt;br /&gt;&lt;br /&gt;Such class-pathish loading model means that classes are manipulated entirely at runtime, and if, for example, you used class A from package a_lib.jar then a_lib can be completely substituted by b_lib.jar if it contains class A with matching interface. If not - only runtime exception will occure. All this means that Inversion of Control (here I'm talking about IoC of classs instantiation) can be acheived transparently, without bringing the complexity of OSGi services.&lt;br /&gt;&lt;br /&gt;Ok, that might've been confusing, but bare with me. Let's see how this would look like in C++ world. All this behavior could've been achieved by explicit class import/export. All of you probably used the implicit dll linkage In this approach entire classes can be exported and imported from dll (although class export is non-standard thus compiler-specific). it's the easiest and transparent way to link to dll. But modular systems can't use implicit linkage because the dll you link to is gennerally not known at compile time. Here C++ suddenly limits our abilities. Just like you using LoadLibrary/GetProcAddress (dlopen/dlsym) to bind functions from dynamically loaded library, why there is no way to link whole classes?&lt;br /&gt;&lt;br /&gt;What we need to know to use the class is its methods, members, constructor and destructor. Member export is quite difficult (it will require the recursive export of types) so best way would be to limit class export to methods only. So this leaves methods, ctor, dtor and class size (so that we could allocate a correct ammount of memory for its instances on client side).&lt;br /&gt;&lt;br /&gt;Instantiation procedure of exported class will generally look like this:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Load a dll with a class you want to use (done explicitly)&lt;/li&gt;&lt;li&gt;Bind ctor, dtor, and all methods of class to their implementation in dll&lt;/li&gt;&lt;li&gt;Allocate suitable ammount of memory on the stack or heap&lt;/li&gt;&lt;li&gt;Call a placement constructor&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Here's how it may look like:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;&lt;br /&gt;//----------------------&lt;br /&gt;// my.dll&lt;br /&gt;//----------------------&lt;br /&gt;&lt;br /&gt;export class MyClass&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;  void Foo();&lt;br /&gt;private:&lt;br /&gt;  int m_bar;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//----------------------&lt;br /&gt;// my_client.exe&lt;br /&gt;//----------------------&lt;br /&gt;&lt;br /&gt;#include "my/myclass.h"&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  import("my.dll"); // Binds class loader chain&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void foo()&lt;br /&gt;{&lt;br /&gt;  MyClass mc; // Triggers lazy type binding&lt;br /&gt;  mc.Foo();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This technique can be implemented in C++, but it would require specifying explicitly which methods to bind, and it will be just too ugly to use. Where it can be used without a tonns of boilerplate code is in D. D has a neat feature, which in my opinion beats the shit out of C++, it's a compile-time reflection. This means that you can iterate over all members of a class for example without writing some ugly method tables etc. Theoretically it can be implemented without being a core language feature, but adding it to the language makes a lot more sense to me.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-9001201556212702743?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/9001201556212702743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/10/in-this-post-i-want-to-describe-small.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/9001201556212702743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/9001201556212702743'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/10/in-this-post-i-want-to-describe-small.html' title='Explicit class import'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-4624207104937371922</id><published>2010-09-07T22:15:00.001+03:00</published><updated>2010-09-07T22:15:44.022+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><title type='text'>Listeners caveats</title><content type='html'>Want to tell about one design problem I keep suffering from day after day. And the problem is in the something as simple as listeners (&lt;a href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer design pattern&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;If you'll ask some programmer to implement listener facility the response would be like: "Ha, peace of cake!". And he instantly writes something like &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern#C.2B.2B"&gt;this&lt;/a&gt;&amp;nbsp;-&amp;nbsp;an interface and &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;std::vector&lt;/span&gt;&lt;/span&gt; of pointers. But this design is initially broken!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Scenario:&lt;/b&gt;&lt;br /&gt;We have a simple game Console system that stores lots of console variable (CVars). Of course Console provides listener facility to track changes of variables (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;OnBeginChange&lt;/span&gt;&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;OnEndChange&lt;/span&gt;&lt;/span&gt;). We have a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;some_variable &lt;/span&gt;&lt;/span&gt;registered in console, and all we want to do is to listen its changes, do some logic in &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;OnEndChange &lt;/span&gt;&lt;/span&gt;and if necessary change its value right there. Changing variable from the on change handler naturally results in recursion, and if you lucky you can eliminate recursion with redundant assignment checks. But in my case a complex server logic was done in handler and values I want to assign vary from call to call.&lt;br /&gt;&lt;br /&gt;Natural quick fix was to unregister my listener before changing the var in the handler and register it back right away. But with typical implementation approach any registration operation will result in hard to diagnose bug, because we end up changing the container while iterating it up on the call stack. Because console was built in release mode I've noticed the bug only because breakpoint in change handler was hit twice during notification (listener was erased and then pushed back on registration).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to do it right:&lt;/b&gt;&lt;br /&gt;Simplest way that will always get you out of trouble is copying the listeners container before the iteration. This way we will only call handlers of those who was registered on the moment of event and allow registration without any side effects.&lt;br /&gt;&lt;br /&gt;Copying approach is simple, but if you are as mush eager for performance as I am, you will feel uncomfortable copying containers every time the event fires. In this case CoW comes to the rescue. CoW stands for Copy-on-Write which is exactly what it does, copies container only in the case when some modification is done. COW can be implemented by wrapping container into &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;shared_ptr&lt;/span&gt;&lt;/span&gt;. When notifying listeners you create another &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shared_ptr&lt;/span&gt;&lt;/span&gt; on stack initializing it with the member. On each registration operation you check for &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shared_ptr::unique()&lt;/span&gt;&lt;/span&gt;, if it is false then notification is running, so we need to duplicate the container, simple!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Listeners and multithreading:&lt;/b&gt;&lt;br /&gt;Consider OSGi event service for example, which asynchronously dispatches bundle events (like &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;BundleStarted&lt;/span&gt;&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;BundleStopped&lt;/span&gt;&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;BundleResolved &lt;/span&gt;&lt;/span&gt;etc.) to other bundles. Simplest implementation would be to store all events in the queue and allocate a thread job that dispatches events in background. Using a bit of locking we can successfully adapt CoW listener list from previous example, all seems fine. But the is a fault, and it is very tricky! Here's the scenario:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Bundle A&lt;/span&gt;&lt;/span&gt; started (event raised, placed in event queue, thread job allocated)&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Bundle B&lt;/span&gt;&lt;/span&gt; started (event raised, placed in event queue)&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Bundle B&lt;/span&gt;&lt;/span&gt; registers as a listener&lt;/li&gt;&lt;li&gt;Finally dispatcher thread is scheduled and delivers events&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Bundle B&lt;/span&gt;&lt;/span&gt; receives &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;A:Started&lt;/span&gt;&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;B:Started&lt;/span&gt;&lt;/span&gt; event (!!!!)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;An OSGi standard dictates that event should be delivered only to those listeners which were registered at the time when event was fired. So &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Bundle B &lt;/span&gt;&lt;/span&gt;should not see its start event and, of course, not the started event of &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Bundle A&lt;/span&gt;&lt;/span&gt;. This means event service should maintain a list of events + listeners registered at the moment it was raised. Sounds very inefficient, but CoW helps here a lot too. Whether it efficient or not, it's not an optimization if you sacrifice correctness, anyway.&lt;br /&gt;&lt;br /&gt;On the second thought you can also use &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;alloca() &lt;/span&gt;&lt;/span&gt;to copy the list of listeners without any heap allocations, but it is not suited for multithread case.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-4624207104937371922?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/4624207104937371922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/09/listeners-caveats.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/4624207104937371922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/4624207104937371922'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/09/listeners-caveats.html' title='Listeners caveats'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-8933013879412981984</id><published>2010-08-07T15:37:00.000+03:00</published><updated>2010-08-07T15:37:16.482+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='languages'/><title type='text'>Dynamic dispatch in D</title><content type='html'>Just discovered one more neat feature of D, the &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;opDispatch()&lt;/span&gt;&lt;/span&gt; operator. Whenever compiler encounters a call to non-existing method such as &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;myObj.Blah(a1, ..., aN)&lt;/span&gt;&lt;/span&gt;&amp;nbsp;and type has an &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;opDispatch &lt;/span&gt;&lt;/span&gt;overload, it transforms a call into &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;myObj.opDispatch!"Blah"(a1, .., aN)&lt;/span&gt;&lt;/span&gt;, making it a function call with a string template argument that contains a function name.&amp;nbsp;It's just a blessing for those who did some script language interop.&lt;br /&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;Some time ago I've implemented a script binding generation library for my engine which were using my C++ Reflection library to create Python type proxies at runtime (a big plus comparing to boost.python, because this model easily works with plug-in and modular design).&lt;br /&gt;&lt;br /&gt;Exposing C++ types to Python was challenging, but I've managed to hide all complexity in the library. The reverse integration, exposing Python types to C++, was a hard thing to do without forcing the user to write a lot of boilerplate code.&lt;br /&gt;&lt;br /&gt;I'm sure in D with this dynamic dispatch feature it is a peace of cake. All script objects can be represented with a single class with &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;opDispatch &lt;/span&gt;&lt;/span&gt;overload in it. A little runtime validation, and you're in scripting haven.&lt;br /&gt;&lt;br /&gt;Hmm, or event better pattern, for stable types with compile-time type checking:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Define the D interface that describes the Python type&lt;/li&gt;&lt;li&gt;Make the &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ScriptObject&lt;/span&gt;&lt;/span&gt;&amp;nbsp;class accept interfaces as a template parameters&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ScriptObject&lt;/span&gt;&lt;/span&gt;&amp;nbsp;inherits this interface and generates all method implementations using &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;traits &lt;/span&gt;&lt;/span&gt;(D's compile-time reflection) and &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mixin &lt;/span&gt;&lt;/span&gt;feature.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;...wow, D really lets your design imagination run wild :)&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-8933013879412981984?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/8933013879412981984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/08/dynamic-dispatch-in-d.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8933013879412981984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8933013879412981984'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/08/dynamic-dispatch-in-d.html' title='Dynamic dispatch in D'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-5073594722801193842</id><published>2010-08-04T22:00:00.002+03:00</published><updated>2010-08-04T22:04:24.325+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='engine'/><title type='text'>Client-Server Engine Architecture</title><content type='html'>You really want to separate client and server parts of your engine. Belive me, because I've been on the other side.&lt;br /&gt;&lt;div class="restofpost"&gt;&lt;br /&gt;Simply put, by client side I mean the part responsible for user input and rendering, and by server - part that contains all game logic, physics simulation, AI and stuff. The dumber the client side - the better.&amp;nbsp;Here's an overview of &lt;a href="http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking"&gt;Source Engine's networking architecture&lt;/a&gt; which elaborates things a bit.&lt;br /&gt;&lt;br /&gt;By separation I mean that the client and server parts are separate entities in the engine (even in single player mode), communicating through well defined message passing system.&amp;nbsp;The separation step isn't always the obvious one, because a lot of code is shared between those two parts. For example take physics simulation. Apart that I said that it runs on server side, there can&amp;nbsp;be client-side simulation as well. It would be a waste to simulate particles and small debries on the server, because those simulation have almost no effect on&amp;nbsp;gameplay, but will consume A LOT of network traffic.&lt;br /&gt;&lt;br /&gt;Clean separation gives an advantage of easily creating dedicated servers for the game later and helps avoiding the hell of presentation and logic coupling. Without it you just end-up with millions of &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if(bDedicated)&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Typical issues of late separation:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Lost control over things that should only work on server or only on client&lt;/li&gt;&lt;li&gt;Performance penalty because server runs unnecessary subsystems&lt;/li&gt;&lt;li&gt;Bandwidth&amp;nbsp;penalty for synchronization of objects that should be client-only&lt;/li&gt;&lt;li&gt;Presentation info used in logic (pierceability and other physics properties depend on material used for rendering)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;It is&amp;nbsp;challenging sometimes, here's a funny example. Consider the&amp;nbsp;rag-doll&amp;nbsp;animation, when player dies his body is physicalized and falls obeying the laws of&amp;nbsp;Newton. Should rag-doll work on client or server?&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Server-side means that all clients see the same picture, but in a cost of huge bandwidth. Client-side simulation is cheap, dead bodies have low impact on gameplay, so it should work...&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But few moth later you receive a request from designers "we want medic to be able to revive fallen comrades by coming near the body and..." you name it. The issue here that the "near the body" part is different on all clients because of non-deterministic behaviour of rag-doll. And yet better, there's no body on the server&amp;nbsp;at all. Also remember that we cannot trust any information from the client besides its input, so no "revived" messages are allowed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Your comments on the puzzle are welcome ;)&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-5073594722801193842?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/5073594722801193842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/08/client-server-engine-architecture.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/5073594722801193842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/5073594722801193842'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/08/client-server-engine-architecture.html' title='Client-Server Engine Architecture'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-4938531563816824982</id><published>2010-07-25T23:11:00.000+03:00</published><updated>2010-07-25T23:11:48.212+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='languages'/><title type='text'>First impressions of D</title><content type='html'>I'm a happy owner of Alexandrescu's new book &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321635361/"&gt;"The D Programming Language"&lt;/a&gt;, due to the lack of time I'm only through one third of it, but already I can say that it turned out pretty good.&lt;br /&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;I was really&amp;nbsp;amazed&amp;nbsp;by the D's expressiveness, for example:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;auto input = [ 2, 6, 4, 2, 3, 9 ];&lt;br /&gt;auto res = reduce!( min, max, (s, x) { return s + x; } ) (input);&lt;br /&gt;writefln("min=%s, max=%s, sum=%s", res._0, res._1, res._2);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Computing the minimum, maximum and a sum across the slice all in one iteration and in a single line, superb.&lt;br /&gt;The other impressive thing for me are tuples, variadic functions and templates.&lt;br /&gt;&lt;br /&gt;Playing with delegates and function pointers I did not really get yet why function pointer is not implicitly convertible to delegate with same signature. Delegates differ only by carrying along the context where they were created, so there no obvious reason to deny the conversion.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void callFoo(void delegate(int x) deleg)&lt;br /&gt;{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;deleg(10);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main()&lt;br /&gt;{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;callFoo(delegate (int x) { writeln(x); }); &amp;nbsp;// OK&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;callFoo(function (int x) { writeln(x); }); &amp;nbsp; // ERROR&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;So it&amp;nbsp;presumably&amp;nbsp;will add some small overhead even in case of context-free callbacks, but fortunately it is not the issue with templates, both delegates and functions can be used there&amp;nbsp;interchangeably. So to make previous&amp;nbsp;&amp;nbsp;example work &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;callFoo &lt;/span&gt;&lt;/span&gt;can be changed this way:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;void callFoo(T)(T deleg)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if(is( typeof( T(0) ) )) // Tricky check for type validity&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;deleg(10);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;While reading the book I often stress-test some cool features using the &lt;a href="http://www.dsource.org/projects/visuald"&gt;Visual D&lt;/a&gt; plug-in for Visual Studio. Lacking in intellisense support, it nicely integrates with IDE, providing all set of properties and project wizards, very convenient. The plug-in seems to be under heavy development, so, at last, my journey for a decent IDE (integration) for D language came to an end.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-4938531563816824982?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/4938531563816824982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/first-impressions-of-d.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/4938531563816824982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/4938531563816824982'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/first-impressions-of-d.html' title='First impressions of D'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-8860001986619815003</id><published>2010-07-15T14:37:00.000+03:00</published><updated>2010-07-15T14:37:13.366+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><title type='text'>Inheritance and lifetime inversion</title><content type='html'>The misuse of inheritance is a common mistake. Previously I thought of it as a thing that leads to a poor and complicated design, but recently found a good example of how it can cause the&amp;nbsp;logical&amp;nbsp;error. The example is&amp;nbsp;especially&amp;nbsp;valuable because illustrates an error made in a heart of the engine - in memory allocator.&lt;br /&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;So&amp;nbsp;suppose we need to make a lot of allocations of objects of some type. This is the ideal situation to apply a free-list allocator. So the author of that code defined a class called &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;FixedSizePoolAllocator&lt;/span&gt;&lt;/span&gt;. This class maintains a free-list of objects so it can give them out when they needed. If the list is empty it allocates an object through &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Heap &lt;/span&gt;&lt;/span&gt;instance (an allocation strategy class), passed to allocator in a constructor by reference. So everything looks peachy now, you create an allocator in your code, pass him a &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Heap &lt;/span&gt;&lt;/span&gt;instance, thats it.&lt;br /&gt;&lt;br /&gt;This design is flexible in that way, that user can share instances of Heap between multiple pools, so if a Heap is some constant-size buffer, all objects will be allocated from it. But for most cases you don't need that flexibility, you just want a pool. With this thought in ming same or another author creates &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;PoolAllocator &lt;/span&gt;&lt;/span&gt;class, which supposed to wrap &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;FixedSizeAllocator &lt;/span&gt;&lt;/span&gt;and provide a &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Heap &lt;/span&gt;&lt;/span&gt;to it. He inherits &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;PoolAllocator &lt;/span&gt;&lt;/span&gt;from &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;FixedSizeAllocator&lt;/span&gt;&lt;/span&gt;, adds a member &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Heap &lt;/span&gt;&lt;/span&gt;object to it, and passes &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;m_heap &lt;/span&gt;&lt;/span&gt;reference to parent constructor.&lt;br /&gt;&lt;br /&gt;Here's the code that illustrates this "solution":&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;template&amp;lt;typename THeap&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;class FixedSizeAllocator&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; FixedSizeAllocator(THeap&amp;amp; pHeap) : m_pHeap(&amp;amp;pHeap)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;~FixedSizeAllocator( )&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;THeap* m_pHeap;&lt;br /&gt;};&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;template&amp;lt;typename THeap&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;class PoolAllocator : FixedSizeAllocator&lt;theap&gt;&lt;/theap&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;PoolAllocator( )&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;: m_heap(...)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;,&amp;nbsp;FixedSizeAllocator(m_heap)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;THeap m_heap;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Take a second and you should be able to identify at least two huge problems in this wrapper (think of an ellipsis as of any operations you can imagine).&lt;br /&gt;&lt;br /&gt;So, design issues aside, here they are:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1.&lt;/b&gt; Compiler don't give a damn in which order you place the statements in constructor initialization list, the order is always the same: first, the constructor of base class is called, then, all members initialized in top-down order as they were written in class (not initialization list). So if&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;FixedSizeAllocator &lt;/span&gt;&lt;/span&gt;will decide to do some operations on heap object, it would do them on yet not constructed invalid object.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;GCC is actually has a warning about wrong order of initialization list&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;2.&lt;/b&gt; Because destructors called in reverse to construction order,&amp;nbsp;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;PoolAllocator &lt;/span&gt;&lt;/span&gt;dtor will be called first, and respectively the destructor of m_heap. So if&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;FixedSizeAllocator &lt;/span&gt;&lt;/span&gt;is doing some operations with &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;m_pHeap &lt;/span&gt;&lt;/span&gt;in his destructor (which it certainly did), you, again, has a big problems.&lt;br /&gt;&lt;br /&gt;So in fact our wrapper never even wraps anything&amp;nbsp;properly, that's what I've called a "lifetime inversion". Maybe there's some another name for it.&lt;br /&gt;&lt;br /&gt;I hope you will now be able to identify such bad patterns in code and won't run into the same problem. It took me at least an hour to get to the core of the problem, navigating through huge call-stacks, partially because I&amp;nbsp;believed&amp;nbsp;that such code is always written by pros and well tested.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusions:&lt;/b&gt;&lt;br /&gt;- Prefer composition over inheritance&lt;br /&gt;- Keep initialization and destruction order in mind&lt;br /&gt;- Test your code (unit-tests, valgrind)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-8860001986619815003?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/8860001986619815003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/inheritance-and-lifetime-inversion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8860001986619815003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8860001986619815003'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/inheritance-and-lifetime-inversion.html' title='Inheritance and lifetime inversion'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-8627754075588673058</id><published>2010-07-12T22:17:00.002+03:00</published><updated>2010-07-13T13:08:56.220+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Biggest blog I ever saw</title><content type='html'>A&amp;nbsp;colleague of mine recommended me a&amp;nbsp;&lt;a href="http://cbloomrants.blogspot.com/"&gt;Cbloom Rants&lt;/a&gt;&amp;nbsp;blog. When I got home I decided to check it out and stuck reading for the whole evening.&lt;br /&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;I have this habit of reading all blogs from the very bottom up to the newest post, so I was surprised to see that first post is dated with December 2000.&lt;br /&gt;&lt;br /&gt;Author is a physicist and programmer, mainly working in gamedev.&amp;nbsp;This guy writes with admirable stability, I've counted 3275 posts in total now, each of which worth reading.&amp;nbsp;It is really amazing how you can just spend one evening reading the 10 years of someone's life, his thoughts on politics, capitalism, war, guns and drugs,&amp;nbsp;bicycles, cars, dating with girls...&amp;nbsp;Some posts are funny, some are sad, some filled with happiness, some with anger.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;"Sometimes I just want to get crazy, to be poor, broke, live in the big city, and do something important, do something to change the world, do something different, like art or music or *something*, to be addicted to drugs, or a criminal. To not just be a cog in the machine, to not just do the same crap that everyone in the world is doing, to not be replaceable, to not enjoy nice wine, to not have a nice car, to not watch television. But then that feeling passes and I go back to doing all those things that I despised a moment ago, because after all, I do like them so."&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;Where else would you find a &lt;a href="http://cbloomrants.blogspot.com/2003/11/11-5-03-2.html"&gt;detailed instruction&lt;/a&gt; of how to act if someone tries to hang you?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;"My oven exploded again. Every time I cook Italian sausage in wine (the only way to do it), the alcohol in the wine explodes in my oven. The first time I did it, it burned off my eye lashes. I wonder if this is common or am I doing something wrong?"&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;At first I wanted to make my blog as consecutive as possible, one thought comes out from another etc. But after reading this blog now I'm convinced - you should just write everything that comes to your mind.&lt;br /&gt;&lt;br /&gt;Being busy all the time at work, at home, I don't really have the time to make (and keep) my blog up-to-date with things I am thinking about. Perhaps later there will be time to gather some posts and build articles about things I've been working on all this time. If not - I bet it will be just awesome even for me to take a look at what I was writing about ten years ago :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-8627754075588673058?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/8627754075588673058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/biggest-blog-ive-ever-saw.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8627754075588673058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/8627754075588673058'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/biggest-blog-ive-ever-saw.html' title='Biggest blog I ever saw'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-6717105870278123878</id><published>2010-07-12T00:21:00.001+03:00</published><updated>2010-07-12T09:55:34.641+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='modular architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>OSGi Future: OSGi-enabled kernel</title><content type='html'>More than half a year passed since I've started working on OSGi topic, implementing OSGi Core first in C++ and now in C#. All this time I read and heard about multiple applications of this technology ranging from embedded devices integration to enterprise application architecture and SOA. There is a positive shift going on in the industry from simple OOP to component-oriented architectures. So I just wanted to share my opinion about what all this leading us to.&lt;br /&gt;&lt;div class="restofpost"&gt;&lt;br /&gt;&lt;b&gt;Plug-in-oriented architecture&lt;/b&gt;&lt;br /&gt;First of all a bit of my personal experience - plug-in-oriented architecture rocks!&lt;br /&gt;Right now I have four large and middle-scale applications successfully built with this approach. There are my game engine, IDE with VHDL compiler, and few tools I've wrote on my job, all built using Eclipse extensions-like approach. By this time I've implemented extension graph for C++, C# and Python languages.&lt;br /&gt;&lt;br /&gt;Judging from examples you can see, that plug-in architecture clearly doesn't have a narrow range of appliances. It helps to&amp;nbsp;structure the program in clearly-defined layers, prevents tight coupling and really helps with reuse. It will&amp;nbsp;definitely help any project that has some considerable development time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;OSGi&lt;/b&gt;&lt;br /&gt;OSGi adds a dynamics to component-based architecture. By dynamics I mean a system-wide notion about that any service in it can go "up" and "down" in any minute. This adds a noticeable amount of complexity, comparing to Eclipse extensions, but the gained benefits&amp;nbsp;definitely&amp;nbsp;worth it. Now all bundles (components/modules/plug-ins in OSGi terminology) can correctly react on presence of some service.&amp;nbsp;Although&amp;nbsp;such dynamics doesn't seem quite useful in a single-process scale, it really shines when R-OSGi comes to stage.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;R-OSGi&lt;/b&gt;&lt;br /&gt;R-OSGi (remote OSGi) is a communication framework in OSGi that adds a possibility to connect OSGi containers running on different machines. Similarly to CORBA or DCOM it implemented in such way that remoting is absolutely transparent to services' user. Remoting layer is fairly similar to WCF, but in contrast, in OSGi it fits to the whole framework concept so seamlessly, that it hides complexity from the user, not introduces it. Dealing with remote machines, the complete component life-cycle helps to react correctly to connection problems etc.&lt;br /&gt;&lt;br /&gt;Simple example of the power of OSGi is Eclipse, which starting from version 3.0 picked it as its runtime architecture. Since then it clearly benefited in distributed sphere. Eclipse Communication Framework grows fast, adding support of new transport protocols (REST, SOAP, XMPP, and even ICQ), support for communication with non-Eclipse web services and more.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Android example&lt;/b&gt;&lt;br /&gt;Recently, thanks to some sneaky-thievy-bastard I was thinking about buying a new phone. Naturally, I was looking for an Android device, and even though I am not, and never been interested in mobile development, just out of curiosity I took a look what it has to offer to developers. I was slightly disappointed by Google's choice of Java as primary development language and Android's API architecture in general.&lt;br /&gt;&lt;br /&gt;First of all Java is clearly looses its positions to .Net. Given that for Android Google implemented their own virtual machine for Java (so they were not forced by some huge amount of legacy code or something) the choice is even stranger. With all their PR talks about freedom of software etc. why not invest those resources in Mono? The obvious win here - much bigger language support (C#, VB, F#, IronPython ... ), instead they limited themselves (and developers) to just one.&lt;br /&gt;&lt;br /&gt;From API-side things are&amp;nbsp;disappointing&amp;nbsp;too. Google takes a limited "&lt;i&gt;program only those things we will let you to&lt;/i&gt;" API approach. This means that when phones with some new cool feature come out you can't do nothing with it, not until it will be exposed in Android API. This is very limiting, where is the promised freedom I ask?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;OSGi-based kernel&lt;/b&gt;&lt;br /&gt;I was able to find some posts about OSGi being ported to Android, but no info on most obvious move from my point of view - integrating OSGi to Androids kernel. Basically cell phone is a large collection of services, communicational (GSM, CDMA, WiFi, Bluetooth ... ), multimedia (Camera, Accelerometer) and so on. All this perfectly fits to the main purpose of OSGi - dynamic service discovery and binding.&lt;br /&gt;&lt;br /&gt;This would greatly improve the API - all you need to do is provide the list of available services with their interfaces and contracts. Service API could be exposed my 3rd-party vendors of some hardware or software feature, significantly decreasing the workload on core system API writers. It will even give developers the ability to program to non-existing yet feature by substituting in development time with a stub-service, so when new feature comes out application will immediately detect and use it!&lt;br /&gt;&lt;br /&gt;Thinking about OSGi-enabled mobile OS, I came to idea of finishing my C++ OSGi implementation and trying to integrate it to the Linux kernel. With some improvements (like security, contexts and service discovery domains) it would be a solid&amp;nbsp;application development platform.&lt;br /&gt;&lt;br /&gt;Judging from Eclipse, which is already overloaded with Twitter, ICQ, Jabber and other plug-ins there is a big demand for a system-wide component framework of this kind.&lt;br /&gt;&lt;br /&gt;With this whole OSGi OS idea it seems to me that I'm&amp;nbsp;coming towards the micro-kernel approach, but I can't define a clear boundary right now.&amp;nbsp;"The time will show": I could've said, but time is&amp;nbsp;definitely not working in my&amp;nbsp;favour&amp;nbsp;:)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;References:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;a href="http://www.eclipsezone.com/articles/extensions-vs-services/"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;A Comparison of Eclipse Extensions and OSGi Services&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;a href="http://www.slideshare.net/j.ritter/osgi-on-android-value-proposition"&gt;OSGi on Android slides&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mobileosgi.blogspot.com/2009/06/update-on-osgi-for-android.html"&gt;Porting of OSGi to Android&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-6717105870278123878?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/6717105870278123878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/osgi-future-osgi-enabled-kernel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/6717105870278123878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/6717105870278123878'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/07/osgi-future-osgi-enabled-kernel.html' title='OSGi Future: OSGi-enabled kernel'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-3566626011734654278</id><published>2010-05-09T22:32:00.001+03:00</published><updated>2010-05-28T11:02:50.410+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='languages'/><title type='text'>D vs. C++</title><content type='html'>Few weeks ago I've stumbled onto the new language named "D". I was very sceptical about all new languages that were released recently, but when I saw that D aims to be a successor of C++ I just had to take a look at it.&lt;br /&gt;&lt;br /&gt;&lt;div class="restofpost"&gt;Because last year I mostly been dealing with the darkest corners of C++ implementing reflection, delegates, data marshalling&amp;nbsp;I was very frustrated that none of the core language problems were addressed in the&amp;nbsp;upcoming&amp;nbsp;C++0x standard (at least standardized layout of pointers to member function would have saved me a lot of nerves). Of course such decisions of&amp;nbsp;committee&amp;nbsp;are understandable, on C++&amp;nbsp;lays&amp;nbsp;the burden of zillions lines of existing code, so breaking changes seem&amp;nbsp;unacceptable.&lt;br /&gt;&lt;br /&gt;Creator of D made a much bigger step than filling C++ with a bunch of syntactic&amp;nbsp;sugar,&amp;nbsp;although&amp;nbsp;D has a similar set of paradigms its features assembled into a whole new level of programming techniques.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Features&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;I really don't want to repeat all the numerous articles about D, so I'll just name most arguable and most pleasant features from my point of view:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;D is a compiled language&lt;/b&gt;, it compiles to the assembly code, what is&amp;nbsp;definitely awesome.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;D has a built-in Unicode support, interfaces, delegates and closures&lt;/b&gt;, what is awesome.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;D is a&amp;nbsp;garbage collected &amp;nbsp;language&lt;/b&gt;, what is awe... Ehm, isn't this too much for a successor of C++ you may ask? At first I was&amp;nbsp;sceptical&amp;nbsp;about this decision, because in the past spent a great deal of time fighting with GC in C# in one memory-hungry application.&lt;br /&gt;&lt;br /&gt;Stroustrup claimed that in C++ you can easily implement your own garbage collection if you really want to. Unfortunately, this is not an easy task,&amp;nbsp;especially&amp;nbsp;when you interfacing with 3rd party libraries. You have to constantly track all the data exchange, making sure that objects passed into the libraries from your code will not be garbage collected, and objects that you receive are deallocated by the rules of the library who created them. With language-wide garbage collection this is not the issue&amp;nbsp;any more.&lt;br /&gt;&lt;br /&gt;So now GC looks totally reasonable to me. Yeah, and most importantly, despite the GC you still get the beloved RAII (see the &lt;i&gt;&lt;b&gt;scope&lt;/b&gt;&lt;/i&gt; feature)!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;D doesn't have a preprocessor&lt;/b&gt;, it uses totally different compilation model which is more efficient than raping the compiler with millions of &lt;b&gt;&lt;i&gt;#include&lt;/i&gt;&lt;/b&gt;'s.&lt;br /&gt;&lt;br /&gt;D addresses multithreading problems by making &lt;b&gt;all variables implicitly thread-local&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;D has a really powerful templates and&amp;nbsp;meta-programming&amp;nbsp;mechanisms&lt;/b&gt;, on top of that the &lt;b&gt;standard library&lt;/b&gt; is written by Andrei Alexandrescu and &lt;b&gt;features &lt;/b&gt;his &lt;b&gt;range concepts&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Here's the small example of its power:&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #000066; font-family: monospace; font-size: 13px; line-height: 18px; white-space: pre;"&gt;&lt;span class="d_keyword" style="color: blue;"&gt;int&lt;/span&gt;[] arr1 = [ 1, 2, 3, 4 ];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #000066; font-family: monospace; font-size: 13px; line-height: 18px; white-space: pre;"&gt;&lt;span class="d_keyword" style="color: blue;"&gt;int&lt;/span&gt;[] arr2 = [ 5, 6 ];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #000066; font-family: monospace; font-size: 13px; line-height: 18px; white-space: pre;"&gt;&lt;span class="d_keyword" style="color: blue;"&gt;auto&lt;/span&gt; squares = &lt;span class="d_psymbol" style="text-decoration: underline;"&gt;map&lt;/span&gt;!(&lt;span class="d_string" style="color: red;"&gt;"a * a"&lt;/span&gt;)(chain(arr1, arr2));&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #000066; font-family: monospace; font-size: 13px; line-height: 18px; white-space: pre;"&gt;&lt;span class="d_keyword" style="color: blue;"&gt;assert&lt;/span&gt;(equal(squares, [ 1, 4, 9, 16, 25, 36 ]));&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #000066; font-family: monospace; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; line-height: 18px; white-space: pre;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #000066; font-family: monospace; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; line-height: 18px; white-space: pre;"&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium; line-height: normal; white-space: normal;"&gt;You can see here following features:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;type inference with &lt;b&gt;&lt;i&gt;auto&lt;/i&gt;&lt;/b&gt; keyword&lt;/li&gt;&lt;li&gt;chaining of two ranges&lt;/li&gt;&lt;li&gt;new template syntax &lt;b&gt;&lt;i&gt;!( ... ) &lt;/i&gt;&lt;/b&gt;that solves the&lt;b&gt;&lt;i&gt; &amp;gt;&amp;gt;&lt;/i&gt;&lt;/b&gt; issue&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;b&gt;mixin &lt;/b&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;is used under the hood to generate code from a string passed as a template argument&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;lazy evaluation - mapping operation will be delayed til' the result of operation is actually needed&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Also there are mind-blowing features like &lt;b&gt;&lt;i&gt;static if&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, a &lt;b&gt;&lt;i&gt;compile-time function evaluation&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt; and &lt;b&gt;compile-time&lt;/b&gt; &lt;b&gt;&lt;i&gt;foreach&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;!!&amp;nbsp;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;And here's the craziest proof of its meta-programming power&amp;nbsp;&lt;a href="http://h3.gd/ctrace/"&gt;http://h3.gd/ctrace/&lt;/a&gt;&amp;nbsp;- a compile-time&amp;nbsp;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;(!)&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&amp;nbsp;&lt;b&gt;raytracer&amp;nbsp;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;(!!)&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;... no words :)&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Downsides&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;There's a lot more features out there, so go ahead and see for yourself, but now I have to tell my opinion about D's downsides.&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;First of all is a god damn name. What do those people think about naming their languages D or Go?! As a result it's very difficult to google info about it.&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Second - I've spend few days just trying to setup a decent working environment to try it out. I was using both &lt;/span&gt;Windows&lt;span class="Apple-style-span" style="font-style: normal;"&gt; and &lt;/span&gt;Linux&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, tried &lt;/span&gt;Eclipse&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, &lt;/span&gt;Code::Blocks&lt;span class="Apple-style-span" style="font-style: normal;"&gt; and &lt;/span&gt;Poseidon&lt;span class="Apple-style-span" style="font-style: normal;"&gt;, but none of them felt right. &lt;/span&gt;Code::Blocks&lt;span class="Apple-style-span" style="font-style: normal;"&gt; felt the best, but when I decided to play with shared libraries in&amp;nbsp;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;D I've discovered that&lt;/span&gt; DMD&lt;span class="Apple-style-span" style="font-style: normal;"&gt; (one of the D compiles) simply doesn't have a shared libraries support yet... Good thing that&amp;nbsp;supposedly&amp;nbsp;&lt;/span&gt;GDC&lt;span class="Apple-style-span" style="font-style: normal;"&gt; (&lt;/span&gt;GCC&lt;span class="Apple-style-span" style="font-style: normal;"&gt; front-end for D (what a name... :)) had, but the bad thing that it was the end of my patience.&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Now I have some Internet connection problems, so I left D and &lt;/span&gt;GDC &lt;span class="Apple-style-span" style="font-style: normal;"&gt;aside for a while, but anyway, the toolset level just seems immature. However, many people claim that they already have released or ongoing commercial projects with D as a main language. There is a hope that D will soon be available for Visual Studio, thanks to&amp;nbsp;&lt;b&gt;Visual D plug-in&lt;/b&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;As a downside I can add a slow migration of tools from &lt;i&gt;D 1.0&lt;/i&gt; to &lt;i&gt;D 2.0&lt;/i&gt;, and the existence of two&amp;nbsp;competing&amp;nbsp;standard libraries:&amp;nbsp;&lt;i&gt;Phobos&lt;/i&gt; and &lt;i&gt;Tango&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;b&gt;Phobos&lt;/b&gt;&lt;/i&gt; is a minimalistic library in C++ style and its style is very appealing to me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;Tango&lt;/i&gt;&lt;/b&gt; is more like a &lt;i&gt;Java&lt;/i&gt;-style huge "&lt;i&gt;I-can-do-everything&lt;/i&gt;" library. Another example of such rich standard library is my beloved &lt;i&gt;Python&lt;/i&gt;.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;From my point of view the ideal solution for them is to coexist. Taking of the "standard" part from the Tango and making it reside on top of low-level Phobos features would be a way to go.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;Summary&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;D looks very promising to me, and I think a great future awaits us with it. D hits the spot&amp;nbsp;satisfying&amp;nbsp;the need of the modern and powerful system programming language. I've already&amp;nbsp;pre-ordered a new Alexandrescu's book, so somewhere&amp;nbsp;in July I will definitely take a deeper look on this great language :)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Links&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.digitalmars.com/d/2.0/garbage.html"&gt;Garbage collection in D, pros and cons&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.digitalmars.com/d/2.0/phobos/std_algorithm.html"&gt;Overview of algorithm library of Phobos&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321635361/modecdesi-20"&gt;Alexandrescu's new book "D Programming Language"&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-3566626011734654278?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/3566626011734654278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/05/d-vs-c.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/3566626011734654278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/3566626011734654278'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/05/d-vs-c.html' title='D vs. C++'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-3699050162315723461</id><published>2010-04-04T15:24:00.002+03:00</published><updated>2010-04-04T15:26:42.286+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='modular architecture'/><title type='text'>Interfaces: Type identification and casting</title><content type='html'>&lt;div align="justify"&gt;&lt;/div&gt;&lt;div align="justify"&gt;As we continue our way towards C++ modularity, there's a few problems yet need to be solved. In this post I will describe type casting between interfaces, and type identification in general.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="restofpost"&gt;&lt;div align="justify"&gt;In my &lt;a href="http://corearchitecture.blogspot.com/2010/03/interface-and-implementation-modules.html"&gt;previous post&lt;/a&gt; I've describe how to export interface implementations from a dynamic library. This solution is sufficient for a beginning, but when your interface hierarchies grow there will be a time when you will have a need to &lt;i&gt;downcast&lt;/i&gt; a pointer (cast from base interface to a specific child). Note, that &lt;i&gt;dynamic_cast &lt;/i&gt;will not work in this case, because we do not export any type (and therefore no type info) from the modules. So this problem is unsolvable without additional facilities.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;QueryInterface&lt;/i&gt; method&lt;/b&gt;&lt;/div&gt;&lt;div align="justify"&gt;The main subject now will be a &lt;i&gt;QueryInterface&lt;/i&gt; method. &lt;i&gt;QueryInterface&lt;/i&gt; is one of the three methods of &lt;i&gt;IUnknown&lt;/i&gt;, which is the base type for all interfaces in COM. Last two methods was mentioned earlier: &lt;i&gt;AddRef&lt;/i&gt; and &lt;i&gt;Release&lt;/i&gt;, used to manipulate the reference count. This is how &lt;i&gt;IUnknown &lt;/i&gt;looks like:&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;struct IUnknown&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; virtual HRESULT QueryInterface(const GUID&amp;amp; iid, void **ppObject) = 0;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; virtual unsigned long AddRef() = 0;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; virtual unsigned long Release() = 0;&lt;br /&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&lt;i&gt;QueryInterface&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; receives two parameters:&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li align="justify"&gt;&lt;span style="font-family: inherit;"&gt;iid - unique identifier (&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;GUID)&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; of the interface we want to cast to&lt;/span&gt;&lt;/li&gt;&lt;li align="justify"&gt;&lt;span style="font-family: inherit;"&gt;ppObject - acts as return parameter that will receive a pointer to interface in case of successful cast&lt;/span&gt;&lt;/li&gt;&lt;li align="justify"&gt;&lt;span style="font-family: inherit;"&gt;finally, &lt;i&gt;QueryInterface &lt;/i&gt;returns &lt;i&gt;HRESULT &lt;/i&gt;- a result code of operation.&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div align="justify"&gt;&lt;span style="font-family: inherit;"&gt;First thing to notice is that types are identified using GUIDs, this means that we should be able to associate a GUID with a type. Since goal of this post is to give you an idea about type casting, I will sacrifice portability for the sake of brevity, and use a Microsoft's compile extension for this. A portable solution will be presented in later posts, but now we will just change our interface like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;struct&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;__declspec(uuid("00000000-0000-0000-c000-000000000046"))&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt; IUnknown&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; ...&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;With &amp;nbsp;GUIDs we now have a way to uniquely identify interfaces in a separately compiled modules. Now that we have all data, t&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;he simplest implementation of &lt;i&gt;QueryInterface&lt;/i&gt; could look like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;class CMyClass: public IMyInterface&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;HRESULT QueryInterface(const GUID&amp;amp; iid, void **ppObject)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; if(iid == __uuidof(IUnknown))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; *ppObject = static_cast&lt;iunknown*&gt;&lt;iunknown*&gt;(this);&lt;/iunknown*&gt;&lt;/iunknown*&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; return S_OK;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; }&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; if(iid = __uuidof(IMyInterface))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;*ppObject = static_cast&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;IMyInterface&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;*&amp;gt;(this);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; return S_OK;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;return E_NOINTERFACE;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A thing to note here is a casting of &lt;i&gt;this&lt;/i&gt; pointer before assigning it to &lt;i&gt;*ppObject&lt;/i&gt;. This looks redundant to explicitly cast a &lt;i&gt;this&lt;/i&gt; pointer to a base class interface, but this is necessary, because in cases of diamond-shaped hierarchies or inheriting the implementation class those pointers would differ, so returned pointer should point exactly to that type of queried interface.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Optimizing &lt;i&gt;QuryInterface&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;This would be very tiring to write implementation of QI every time by hand, and also not performance-wise. The approach used by COM is a table version of QI. In it all supported interfaces are defined using a set of macros. Those macros compile to a static array of entries containing interface ID and corresponding offset that should be applied to &lt;i&gt;this&lt;/i&gt; pointer when queried. The implementation can be found in the Don Box book, or in ATL source code, I will just provide a sample how it changes code from previous example.&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;class CMyClass: public IMyInterface&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; DECLARE_IMPLEMENTATION(&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;CMyClass&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; BEGIN_INTERFACE_MAP()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; INTERFACE_ENTRY(&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;IMyInterface&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; END_INTERFACE_MAP()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family: inherit;"&gt;Class identification&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Imagine that you have a module that contains two implementations of one system, lets say OpenGL and DirectX renderers. They both implement same interface and intended to be used interchangeably. But now user has no way to choose between them, because all he sees is an interface. This brings us to a solution, that implementation classes should be also identified by GUIDs. We will not use the __declspec(uuid(...)) in this case of course, because header with implementation class should be inaccessible to the user. Instead, we just define a class ID in some other header file:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;static const GUID CLSID_COGLRenderer =&lt;br /&gt;{ 0x637b1ed1, 0x12e5, 0x4a4b, { 0xb6, 0x9d, 0xed, 0xf6, 0xea, 0xd5, 0xc4, 0x78 } };&lt;br /&gt;&lt;br /&gt;static const GUID CLSID_CDX9Renderer =&lt;br /&gt;&amp;nbsp;{ 0x07a4b5f9, 0x495c, 0x45b1, { 0xbb, 0x91, 0xe8, 0xfb, 0x11, 0x44, 0x7c, 0x05 } };&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family: inherit;"&gt;Factory functions&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Class ID solution presented above is cool in two ways: first, it allows us to specify which &amp;nbsp;implementation to use exactly, second, we can reduce the amount of functions exported from a DLL to one.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;extern "C" HRESULT create_instance(const GUID&amp;amp; clsid, const GUID&amp;amp; iid, void** ppObject)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; ...&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;}&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;We use three parameters here: the class ID that should be created, an interface ID the pointer should be cast to before returning it, and the output parameter itself.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-3699050162315723461?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/3699050162315723461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/04/interfaces-type-identification-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/3699050162315723461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/3699050162315723461'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/04/interfaces-type-identification-and.html' title='Interfaces: Type identification and casting'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-1964051042631034366</id><published>2010-03-14T14:56:00.007+02:00</published><updated>2010-03-29T23:55:37.851+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamic binding'/><category scheme='http://www.blogger.com/atom/ns#' term='binary encapsulation'/><category scheme='http://www.blogger.com/atom/ns#' term='modular architecture'/><title type='text'>Interfaces: Modules and Lifetime</title><content type='html'>&lt;div align="justify"&gt;The &lt;i&gt;PImpl&lt;/i&gt; is a practical &amp;nbsp;and easy to use solution. It is suitable for simple utility libraries, but it definitely cannot satisfy all needs of modular architecture. In this post i will describe how a greater flexibility can be achieved by separating interface and implementation.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="restofpost"&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;b&gt;PImpl limitations&lt;/b&gt;&lt;/div&gt;&lt;div align="justify"&gt;Modular (or plug-in)&amp;nbsp;architecture assumes that one type of functionality (a &lt;i&gt;service&lt;/i&gt;) can be implemented by multiple modules in a different way. For example, lets take a configuration persistence service. A single interface to this service can have a variety of different underlying implementations: an &lt;i&gt;xml&lt;/i&gt; or &lt;i&gt;ini&lt;/i&gt;-file serialization, &lt;i&gt;SQLite&lt;/i&gt; or another database connector, etc.&lt;/div&gt;&lt;div align="justify"&gt;Ideally, we should be able even switch implementations without recompiling the application. This is of course impossible task for a &lt;i&gt;PImpl&lt;/i&gt;. There are two reasons for this:&lt;/div&gt;&lt;ul align="justify"&gt;&lt;li&gt;&lt;i&gt;PImpl&lt;/i&gt; &amp;nbsp;implies implicit linking, what means that we always define a concrete shared library to link with&lt;/li&gt;&lt;li&gt;With &lt;i&gt;PImpl &lt;/i&gt;we always specify a concrete type of class to instantiate&lt;/li&gt;&lt;/ul&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;Interfaces&lt;/b&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="justify"&gt;All mentioned above brings us to first conclusion: we should unify "module interfaces" first, ie a set of functions exported from them. The solution here is to export a factory function, something like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;create_cfgstorage_instance()&lt;/span&gt;.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;Hmm, but what should be return type of such function? If we are trying to generalize all configuration storage types, naturally, it should be some base type of those (a &lt;i&gt;superclass&lt;/i&gt;). This superclass won't have any default implementation, so all functions should be pure virtual.&amp;nbsp;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;With this decision, in fact, we solve two problems simultaneously, because virtual functions all have a unified call procedure on all compilers (ie taking an pointer to a virtual table and jumping to &lt;i&gt;N&lt;/i&gt;'th entry of it). This means that compiler can generate code for &lt;i&gt;vcall&lt;/i&gt;, without knowing the true type of the object.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;This &amp;nbsp;abstract type is our &lt;i&gt;interface&lt;/i&gt;! To clarify here's the example:&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;// IConfigStorage.h&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;struct IConfigStorage&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;virtual void WriteValue(&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; const char* key,&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; const char* value) = 0;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;virtual &amp;nbsp;const char* ReadValue(const char* key) = 0;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;...&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;// CINIConfig.h&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;class CINIConfig : public IConfigStorage&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;// Implementation&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&amp;nbsp; &amp;nbsp;...&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;};&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;// CINIConfig.cpp&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;extern "C" &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;__declspec(dllexport)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;IConfigStorage* &amp;nbsp;create_cfg_instance()&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;return new CINIConfig();&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-size: small;"&gt;Nice! Now you can create objects from shared libraries using explicit linking. All you need is to load a library using &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-size: small;"&gt;LoadLibrar&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;y / dlopen&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt; and get the address of&amp;nbsp;&lt;i&gt;create_cfg_instance()&lt;/i&gt; with &lt;i&gt;GetProcAddress / dlsym&lt;/i&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;Object Lifetime&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;You can use your object now, but you can't delete it yet by two reasons:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul align="justify"&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;First, you should&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;never &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;try delete anything allocated in another module (because this module could be compiled with different CRT version, what will cause the memory corruption)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Second, we did not exported a destructor for the object, so compiler will give us an '&lt;i&gt;unresolved external&lt;/i&gt;' error&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;You may think that adding a virtual destructor to the interface might help, but it won't, because standard specifies only the layout of pure virtual functions, but not the virtual destructor. There are two simple solutions here:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul align="justify"&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;add second exported function &lt;i&gt;destroy_cfg_instance()&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;or add a interface member function &lt;i&gt;Free&lt;/i&gt;(), that can be implemented as&lt;i&gt; delete *this&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;Reference counting&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;COM offers more practical solution - an embedded reference counter. This means that interface has two methods: &lt;i&gt;AddRef&lt;/i&gt; and &lt;i&gt;Release&lt;/i&gt; - first increments the reference count, second decrements, and if it reaches zero calls &lt;i&gt;delete *this&lt;/i&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;At first glance this reference counting can be made non-intrusive, by using special type of &lt;i&gt;shared_ptr&lt;/i&gt;, that calls &lt;i&gt;Free&lt;/i&gt; instead of &lt;i&gt;delete&lt;/i&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;But &lt;i&gt;shared_ptr&lt;/i&gt; implementation involves one more allocation for reference counter, that should be deallocated too, so we can't pass this shared_ptr across different subsystem modules by the reasons described earlier. And this brings us to the same problem we were trying to solve :)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;First &amp;nbsp;step completed!&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Congrats, we already achieved a lot, compared to &lt;i&gt;PImpl&lt;/i&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;We can create a simple modular applications with substitutable components&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;We maintain binary encapsulation of modules, while greatly reducing the size of library export table&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;All comes with the price of course, interfaces add cost of virtual call to all methods, but assuming that we mainly export only a subsystem facade's, this is often negligible compared to the gained flexibility.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Interfaces have much more hidden power. In my next post I will describe the type casting between interfaces, introduce the &lt;i&gt;IUnknown&lt;/i&gt;, and generalize the factory functions of our modules.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;References:&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;a href="http://www.amazon.com/ATL-Internals-Working-2nd/dp/0321159624"&gt;Cristopher Tavares "ATL Internals"&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Essential-COM-Don-Box/dp/0201634465"&gt;Don Box "Essential COM"&lt;/a&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-1964051042631034366?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/1964051042631034366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/03/interface-and-implementation-modules.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/1964051042631034366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/1964051042631034366'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/03/interface-and-implementation-modules.html' title='Interfaces: Modules and Lifetime'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-7656097613502029917</id><published>2010-03-07T22:56:00.009+02:00</published><updated>2010-03-29T23:47:21.146+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='binary encapsulation'/><title type='text'>The PImpl idiom</title><content type='html'>&lt;div align="justify"&gt;In my previous post I've described how dangerous implicit linking is. Now I'll show a simple way to make your implicitly-liked libraries safe to modify, without braking the clients who depend on it. This way is called the PImpl idiom. PImpl stands for a "pointer to implementation". So, let's see what this idiom implies.&lt;/div&gt;&lt;div class="restofpost"&gt;&lt;div align="justify"&gt;As was earlier said, the binary encapsulation violation occurs when object exported form DLL changes its size, thereby corrupting memory inside binary who links to it. What we need is to isolate user's code from changes of data members of the exported classes (this often called a compilation firewall). PImpl does this by separating data members into another object, adding a level of indirection. Consider following class:&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;// MatrixStack.h&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include "Matrix.h"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;vector&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;class UTILS_API MatrixStack&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;public:&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;void push_back(const Matrix&amp;amp; m);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;...&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;private:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;std::vector&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;Matrix&amp;gt; m_stack;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;// MatrixStack.cpp&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include "MatrixStack.h"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;void MatrixStack::&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;push_back(const Matrix&amp;amp; m)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;m_stack.push_back(m);&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: inherit;"&gt;You may think that this/yours class is simple and will not likely ever be changed, and you don't need any compilation firewall. But be careful, in this&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; case&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;, for example, we have a std::vector as data member of our class, and its size can vary, based on a compilation options, so firewall is a MUST.&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;// MatrixStack.h&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include "Matrix.h"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include &amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;#include &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;memory&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;class UTILS_API MatrixStack&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;public:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;MatrixStack();&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;~MatrixStack();&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;void push_back(const Matrix&amp;amp; m);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;...&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;private:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;struct MatrixStack_Impl;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;std::auto_ptr&lt;matrixstack_impl&gt; m_pimpl;&lt;/matrixstack_impl&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;// MatrixStack.cpp&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include "MatrixStack.h"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;struct MatrixStack::MatrixStack_Impl&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;{&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;std::vector&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;Matrix&amp;gt; stack;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;};&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;MatrixStack::MatrixStack()&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;: m_pimpl(new MatrixStack_Impl)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;{ &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;}&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;MatrixStack::~MatrixStack()&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;{ }&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;void MatrixStack::&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;push_back(const Matrix&amp;amp; m)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;m_pimpl-&amp;gt;stack.push_back(m);&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, &amp;quot;Courier&amp;quot;, monospace;"&gt;&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;That simple! Let's break into the steps what we did.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;First we forward-declare the &lt;i&gt;*_Impl&lt;/i&gt; structure, we implement it in a cpp file, where user cannot see it, and move all data members to it. Then we add an &lt;i&gt;auto_ptr&lt;/i&gt; pointing to that struct (thus the only member of our class will always be a single pointer). Last thing - we add an initialization of the pointer in class constructor and redirect all data manipulations to the &lt;i&gt;Impl&lt;/i&gt; struct.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;The interesting thing to note here is, on the first thought redundant destructor, which does nothing. But, in fact, it is necessary, and should be implemented in cpp file after the definition of &lt;i&gt;Impl&lt;/i&gt; struct. This is all because default destructor will be generated in place, where definition of &lt;i&gt;Impl&lt;/i&gt; is not accessible, so &lt;i&gt;auto_ptr&lt;/i&gt; will not be able to destroy it properly.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Using &lt;i&gt;auto_ptr&lt;/i&gt; is convenient, however compiler may generate a warning, complaining that &lt;i&gt;auto_ptr&lt;/i&gt; is not exported from the DLL. This happens because it tries to export all members of class, including private. You can either ignore the warning, or just use plain pointer. I personally prefer last option, and, thanks to test driven development, it is always noticeable when delete call in destructor is missing.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;Drawbacks of PImpl:&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Additional allocation&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Makes code more difficult to read&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Performance hit due to indirection&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;Doesn't work for &lt;i&gt;protected&lt;/i&gt; data members&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;b&gt;&amp;nbsp;References:&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;a href="http://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0201924889"&gt;Scott Meyers "Effective C++"&lt;/a&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;a href="http://www.amazon.com/Exceptional-Engineering-Programming-Problems-Solutions/dp/0201615622"&gt;Herb Sutter "Exceptional C++"&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; &lt;i&gt;*&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;i&gt;&amp;nbsp;*&lt;/i&gt; Beware, the trick for eliminating the allocation overhead, presented in this book, will break the compilation firewall, it is only can be used (but not recommended) for minimizing a build time.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-7656097613502029917?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/7656097613502029917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/03/pimpl-idiom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/7656097613502029917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/7656097613502029917'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/03/pimpl-idiom.html' title='The PImpl idiom'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6265149071939082693.post-757275558551027424</id><published>2010-03-07T15:25:00.011+02:00</published><updated>2010-07-12T23:44:23.393+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compilers'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic binding'/><category scheme='http://www.blogger.com/atom/ns#' term='binary encapsulation'/><title type='text'>Flaws of the C++</title><content type='html'>&lt;div align="justify"&gt;Being a huge C++ fan, it should be weird to name my first post like that. Nevertheless, every developer must clearly understand the limitations of the tools he uses, and that's what this post all about.&lt;/div&gt;&lt;div class="restofpost"&gt;&lt;div align="justify"&gt;Those limitations I will discuss were nicely covered by Don Box in his book &lt;a href="http://www.amazon.com/Essential-COM-Don-Box/dp/0201634465"&gt;"Essential COM"&lt;/a&gt;.&lt;/div&gt;&lt;div align="justify"&gt;Some may say that COM is now obsolete, what is probably true, but the problems it addressed are still not solved, and a lot of large-scale C++ projects use COM-like techniques to deal with them.&lt;/div&gt;&lt;blockquote align="justify"&gt;COM is more a programming discipline than a technology&amp;nbsp;&lt;/blockquote&gt;&lt;div align="justify"&gt;Fundamental weakness of C++ is a lack of standardization at the binary level. If you used C++ mostly for development of stand-alone single executable applications you've never faced those issues before. But for a large-scale projects, that involve multiple binaries, each evolving on it's own, the knowing of those is a mandatory.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;b&gt;Dynamic Binding and Name Mangling&lt;/b&gt;&lt;/div&gt;&lt;div align="justify"&gt;As your project grows, you want to minimize the amount of duplicated code by extracting it to shared libraries. As you know, there are two ways of binding: implicit (using a generated static library), and explicit (using &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;LoadLibrary/dlopen&lt;/span&gt; and &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;GetProcAddress/dlsym&lt;/span&gt;). The first is the easiest, it allows to export whole classes form dll, and then link to them in user binary.&lt;/div&gt;&lt;div align="justify"&gt;The problem arises when you try to distribute your library. C++ compilers use technique known as a name mangling to allow export multiple functions with the same name, but from a different namespaces, and with different types and number of parameters, without braking the C-based linkers. Unfortunately, many compiler vendors decided to implement their own mangling scheme. This means that library compiled with one compiler will likely not be able to link used with another compiler. Needless to say, how that complicates the deployment process for middleware.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;b&gt;Binary Encapsulation&lt;/b&gt;&lt;/div&gt;&lt;div align="justify"&gt;So you are a good programmer, you carefully design your classes and hide data using private and protected areas. Unfortunately, this is all useless on binary level. C++ provides only a &lt;i&gt;syntactic &lt;/i&gt;encapsulation, leaving your data bare exposed when code is compiled. This problem arises when you deal with shared libraries. Choosing an implicit binding and exporting classes from your shared libraries you bring yourself to a nightmare of binary incompatibility.&lt;/div&gt;&lt;div align="justify"&gt;Class export allows you creating instances of those on the stack or as members of other classes, what makes user code dependent on size of exported objects. Imagine you have a utility shared library (called &lt;span style="font-family: inherit;"&gt;&lt;i&gt;MyUtils&lt;/i&gt;&lt;/span&gt;) and a executable project which uses it (called &lt;i&gt;MyProject&lt;/i&gt;). &lt;i&gt;MyUtils&lt;/i&gt; exports class called &lt;i&gt;UtilityClasss&lt;/i&gt;. In first version of &lt;i&gt;MyUtils UtilityClass&lt;/i&gt; had 8 bytes size. You compile your project with this version of library and it works great, so great in fact that you decide to ship it.&amp;nbsp;&lt;/div&gt;&lt;div align="justify"&gt;Some time later you discover a neat way to improve performance of &lt;i&gt;UtilityClass&lt;/i&gt; by adding some caching, thus increasing its size to 12 bytes. You compile your solution and test it, and it works fine. Being enthusiastic, you want to send a new version of&lt;i&gt; MyUtils.dll &lt;/i&gt;to users so that they will benefit from improved performance, and immediately your mailbox are full of crash reports.&lt;/div&gt;&lt;div align="justify"&gt;The problem is illustrated below.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_RY4uceDDN4U/TDt-kM0Wv4I/AAAAAAAAACc/WbkPLJzWtr0/s1600/Binary+Encapsulation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="182" src="http://4.bp.blogspot.com/_RY4uceDDN4U/TDt-kM0Wv4I/AAAAAAAAACc/WbkPLJzWtr0/s400/Binary+Encapsulation.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify" class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div align="justify" class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div align="justify" class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div align="justify"&gt;Being separately compiled, the deployed version of &lt;i&gt;MyProject&lt;/i&gt; believes &lt;i&gt;UtilityClass&lt;/i&gt; size to be 8 bytes. So when you replaced the DLL with new one it started to corrupt the memory around.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;b&gt;Exception model&lt;/b&gt;&lt;/div&gt;&lt;div align="justify"&gt;Don Box refers to exceptions as objects "untouchable" by code generated with another compiler. A C++ exception thrown from DLL compiled with mingw cannot be caught reliably by program generated by Microsoft compiler. "Cannot be caught reliably" in many cases means that when the exception is thrown the application will most likely crash and burn.&lt;br /&gt;Exception catching of a user defined type in a binary other than the one which threw the exception requires a &lt;i&gt;typeinfo&lt;/i&gt; lookup, so you need assure that exception types are exported properly. The same thing is required for &lt;i&gt;dynamic_cast&lt;/i&gt; to work.&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;Whew, this post has grown huge. The compilers have much more surprises for you, in addition to those described here. In my next posts I will describe few more of them, and most importantly, the ways to deal with them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;References:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Essential-COM-Don-Box/dp/0201634465"&gt;Don Box "Essential COM"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="v1" href="http://www.amazon.com/Imperfect-Practical-Solutions-Real-Life-Programming/dp/0321228774" target="_new"&gt;Matthew Wilson "Imperfect C++"&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;ul&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265149071939082693-757275558551027424?l=corearchitecture.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://corearchitecture.blogspot.com/feeds/757275558551027424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://corearchitecture.blogspot.com/2010/03/fails-of-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/757275558551027424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6265149071939082693/posts/default/757275558551027424'/><link rel='alternate' type='text/html' href='http://corearchitecture.blogspot.com/2010/03/fails-of-c.html' title='Flaws of the C++'/><author><name>Sergey Mikhtonyuk</name><uri>http://www.blogger.com/profile/14119054565362226711</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_RY4uceDDN4U/TDt-kM0Wv4I/AAAAAAAAACc/WbkPLJzWtr0/s72-c/Binary+Encapsulation.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
