<?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-9064003576220513352</id><updated>2012-01-10T04:13:00.106-08:00</updated><category term='creativity'/><category term='software  design'/><category term='career'/><category term='metacomments'/><category term='distributed computing'/><category term='software implementation'/><title type='text'>Jeeves with Classes</title><subtitle type='html'>The problem of software universals, the theory of virtual Forms, and the Zen of printer drivers.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>rc</name><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>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9064003576220513352.post-4055574541500321038</id><published>2012-01-09T07:56:00.000-08:00</published><updated>2012-01-10T03:11:38.146-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software implementation'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>The time_t's Are a-Changin' (into system_clock Time Points)</title><content type='html'>2011 came and went, but left us with a new ISO &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; standard, codenamed &lt;a href="https://en.wikipedia.org/wiki/C%2B%2B11" style="font-style: italic;"&gt;C++11&lt;/a&gt;. I've looked for an updated edition of &lt;a href="http://www.amazon.com/Programming-Language-3rd-Bjarne-Stroustrup/dp/0201889544"&gt;"The &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; Programming Language"&lt;/a&gt;, or at least some other full-sized book on the subject, but the best I've been able to find at the time of writing this is &lt;a href="http://www.artima.com/shop/overview_of_the_new_cpp"&gt;&lt;span class="as"&gt;Scott Meyers' "&lt;/span&gt;&lt;/a&gt;&lt;span class="ts"&gt;&lt;a href="http://www.artima.com/shop/overview_of_the_new_cpp"&gt;Presentation Materials: Overview of the New &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt;"&lt;/a&gt;, as &lt;a href="http://herbsutter.com/2011/11/01/scott-meyerss-c11-materials-the-best-available-overview-of-c11/"&gt;recommended by Herb Sutter&lt;/a&gt;.&lt;/span&gt; It's not perfect (it doesn't cover everything, it does have a few bugs, and it's not &lt;span style="font-style: italic;"&gt;completely&lt;/span&gt; up to date with &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt;), but it's good and required reading for serious &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; developers.&lt;br /&gt;&lt;br /&gt;Probably the single most important change in the language itself is the addition of &lt;a href="http://thbecker.net/articles/rvalue_references/section_01.html"&gt;rvalue references&lt;/a&gt;, with all that comes along with them, such as &lt;a href="http://www.devx.com/cplus/10MinuteSolution/34577/1954"&gt;move semantics&lt;/a&gt; and &lt;a href="http://thbecker.net/articles/rvalue_references/section_07.html"&gt;perfect forwarding&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm happy to see &lt;span style="font-style: italic;"&gt;auto_ptr&lt;/span&gt;, with it's freak copy-is-move semantics, go away to be replaced by &lt;span style="font-style: italic;"&gt;unique_ptr&lt;/span&gt;. I'm also very happy to see added support for &lt;a href="http://www.devx.com/cplus/10minutesolution/28347/1954"&gt;custom deleters&lt;/a&gt; in the new &lt;span style="font-style: italic;"&gt;_ptr&lt;/span&gt; classes: that makes the problem of resource acquisition and release that &lt;a href="http://jeeveswithclasses.blogspot.com/2008/05/cc-rule-never-locally-release-resource.html"&gt;I've written about here&lt;/a&gt; easier to handle.&lt;br /&gt;&lt;br /&gt;Anything involving callbacks is now easier, thanks to &lt;a href="http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.4/a00375.html"&gt;function&lt;/a&gt;. And good riddance to exception specifications and the (template-related) &lt;span style="font-style: italic;"&gt;export&lt;/span&gt; keyword that almost no &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; compiler implemented anyway!&lt;br /&gt;&lt;br /&gt;There's now support for writing multithreaded applications, but &lt;span style="font-style: italic;"&gt;semaphore&lt;/span&gt; classes are conspicuously missing. You can simulate a semaphore with &lt;span style="font-style: italic;"&gt;condition_variable&lt;/span&gt;s, but that misses out on native OS semaphore support. Why semaphores didn't make it into &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt;, I can't imagine. And why no sockets in &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt;? They're as ubiquitous and necessary today as &lt;span style="font-style: italic;"&gt;mutex&lt;/span&gt;es.&lt;br /&gt;&lt;br /&gt;I'm disappointed to see that a subtle feature that would have solved a lot of issues did not get into &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt;: the compiler could (and in my humble opinion, should) make all destructors of classes with at least one virtual member function virtual as well. A class with a virtual member function is most likely meant to be inherited from, and in case the destructor releases some resource, destroying a derived object through a base class pointer is very dangerous, unless the base class' destructor is virtual. Making it virtual by default in such a case would thus greatly improve safety.&lt;br /&gt;&lt;br /&gt;There are, of course, plenty of other new things in &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt;: variadic templates, Java-like inherited (and delegating) constructors, the &lt;span style="font-style: italic;"&gt;auto&lt;/span&gt; keyword (guess what that does), range &lt;span style="font-style: italic;"&gt;for()&lt;/span&gt; statements, and so on.&lt;br /&gt;&lt;br /&gt;You might like to read &lt;a href="http://www2.research.att.com/%7Ebs/C++0xFAQ.html"&gt;Bjarne Stroustrup's &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt; FAQ&lt;/a&gt;, where, in response to &lt;span style="font-style: italic;"&gt;"what do you think of C++11?"&lt;/span&gt;, he states that he's &lt;span style="font-style: italic;"&gt;"still an optimist"&lt;/span&gt;. &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; started as &lt;span style="font-style: italic;"&gt;"C with classes"&lt;/span&gt;, making it easier than stuffing pointers-to-function into structs. Then, it got templates, adding generic programming to its object-oriented and procedural capabilities. Then, Lisp-like functional programming got added on top of the generic programming support with the popularity of template meta-programming. While it's still true that, with &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; (&lt;span style="font-style: italic;"&gt;11&lt;/span&gt; or otherwise), you don't pay for what you don't use, it's also still true that &lt;span style="font-style: italic;"&gt;you have to&lt;/span&gt;&lt;span style="font-style: italic;"&gt; know about almost everything&lt;/span&gt; in order not to accidentally shoot yourself in the foot. And everything is getting bigger. &lt;i&gt;C++&lt;/i&gt; is one of the areas of software development where &lt;span style="font-style: italic;"&gt;"junior"&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;"senior programmer"&lt;/span&gt; are heavily meaningful terms. If your company can't afford at least a senior mentor to 2-3 junior &lt;span style="font-style: italic;"&gt;C++&lt;/span&gt; programmers, you might be better off using plain &lt;span style="font-style: italic;"&gt;C&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;Java&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;C#&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt; improves some things, leaves others out, and complicates yet others (e.g. &lt;span style="font-style: italic;"&gt;container::cbegin()&lt;/span&gt;/&lt;span style="font-style: italic;"&gt;container::cend() &lt;/span&gt;added for &lt;span style="font-style: italic;"&gt;auto&lt;/span&gt;). If you're comfortable with &lt;span style="font-style: italic;"&gt;C++98&lt;/span&gt;, there's still plenty of time to get acquainted with it's features (and quirks), since most compilers don't yet fully support it. It'll be some time until &lt;span style="font-style: italic;"&gt;C++11&lt;/span&gt; gets fully implemented by compiler vendors, and it is very likely that some of it's features will never be implemented by some of them (just like &lt;span style="font-style: italic;"&gt;C++98&lt;/span&gt;'s template &lt;span style="font-style: italic;"&gt;export &lt;/span&gt;keyword). This is what &lt;span style="font-style: italic;"&gt;GCC 4.5.3&lt;/span&gt; had to say to me today (on my &lt;span style="font-style: italic;"&gt;Gentoo Linux &lt;/span&gt;system):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;$ g++ future.cpp &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/thread:35:0,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;                 from future.cpp:2:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/c++0x_warning.h:31:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-4055574541500321038?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/4055574541500321038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=4055574541500321038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/4055574541500321038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/4055574541500321038'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2012/01/timets-are-changin-into-systemclock.html' title='The time_t&apos;s Are a-Changin&apos; (into system_clock Time Points)'/><author><name>rc</name><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-9064003576220513352.post-19366839635296910</id><published>2008-12-06T11:48:00.000-08:00</published><updated>2012-01-10T03:11:58.674-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='creativity'/><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>Punk Rock Programming</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_BYIkYo9cnnw/STrXwda44ZI/AAAAAAAAABw/t-u6vyFv3Mw/s1600-h/ramones01.jpg"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5276767140949057938" src="http://2.bp.blogspot.com/_BYIkYo9cnnw/STrXwda44ZI/AAAAAAAAABw/t-u6vyFv3Mw/s320/ramones01.jpg" style="cursor: pointer; float: left; height: 238px; margin: 0pt 10px 10px 0pt; width: 320px;" /&gt;&lt;/a&gt;Having had the privilege to experience a couple of days' worth of temporary tinnitus due to attending &lt;a href="http://www.myspace.com/markyramone"&gt;Marky Ramone's Blitzkrieg&lt;/a&gt; show (picture courtesy of &lt;a href="http://www.rockxpress.ro/galerii/ramones.html"&gt;rockXpress.ro&lt;/a&gt;), I've been thinking about a conversation I've had a few years ago with an ex-colleague about C and C++. Why? I'll tell you in a minute, but first: if you don't know who the &lt;a href="http://en.wikipedia.org/wiki/Ramones"&gt;Ramones&lt;/a&gt; are, give them a &lt;a href="http://www.last.fm/music/Ramones"&gt;listen right now&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now, my then colleague expressed his reservations about the continued use of the C programming language. He argued that C is now mostly a subset of C++, therefore C should probably be better off put away somewhere and forgotten. No more separate committees for ANSI C and ISO C++, resources spent more efficiently, and so on. The argument has some justice to it, and I'm sure the hardcore geek readers' eyes are gleaming with anticipation of a rainy weekend with a hot technical debate over whether compiling with one compiler for both programming styles should generate exception handlers for the low-level code by default, but that's really not what I want to talk about.&lt;br /&gt;&lt;br /&gt;What I want to talk about is the human component to using a tool such as a guitar, or a programming language. Programmers tend to believe the myth that efficiency has to be desired at all costs, and by organizing the code, and indeed the workplace in a certain "One True (TM)" manner all will be well with the world. Incidentally, so did the Nazis.&lt;br /&gt;&lt;br /&gt;But there's a big difference in the overall philosophy of most of the people who prefer C vs. the axioms of the people who prefer C++.&lt;br /&gt;&lt;br /&gt;C++ is more like classical music. If you want to be a classical music composer, or simply a competent classical music instrument player, you need to train a lot for dexterity, to master the music modes, to understand how intervals and modes relate to chords, to study the work of the great composers, to learn sight-reading music, and so on. So you have your Mozart, your Mahler, and your Yehudi Menuhin.&lt;br /&gt;&lt;br /&gt;But, what if someone simply enjoys music, and wants to have fun with it? Make the best of what one can learn in a short time with limited resources? After all, my high school psychology manual used to define one's level of intelligence as being directly related to one's capacity of doing more with less. So then, you have your Ramones, your Nirvana, your Stooges, your Mudhoney. Two-note chords, at most five distinct chords in a song. Cheap one-pickup guitars. But you react to it. Things get done. You're moved by it, not in the same way as you would with classical music, but neither in a way that's better or worse.&lt;br /&gt;&lt;br /&gt;C gets things done. It's almost assembly language, but then again it's not. It's direct access to your computer. And you can learn it from a less-than 100 pages book ("&lt;a href="http://netlib.bell-labs.com/cm/cs/cbook/"&gt;K&amp;amp;R&lt;/a&gt;"), as opposed to the ten times as thick "&lt;a href="http://www.research.att.com/%7Ebs/3rd.html"&gt;The C++ Programming Language&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;Both languages have their place, and as long as they will be actively supported by their respective committees (and more importantly, their developer communities),  this will continue to be the case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-19366839635296910?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/19366839635296910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=19366839635296910' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/19366839635296910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/19366839635296910'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/12/punk-rock-programming.html' title='Punk Rock Programming'/><author><name>rc</name><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://2.bp.blogspot.com/_BYIkYo9cnnw/STrXwda44ZI/AAAAAAAAABw/t-u6vyFv3Mw/s72-c/ramones01.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9064003576220513352.post-97155719286850700</id><published>2008-10-11T09:28:00.000-07:00</published><updated>2012-01-10T03:12:23.374-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='creativity'/><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><title type='text'>The GPS Coordinates of Jung's Tower</title><content type='html'>As technology workers, we're all too familiar with pro-technology arguments. However, &lt;a href="http://www-cs-faculty.stanford.edu/%7Euno/"&gt;Donald Knuth&lt;/a&gt;, author of "&lt;a href="http://en.wikipedia.org/wiki/The_art_of_computer_programming"&gt;The Art of Computer Programming&lt;/a&gt;", and king of the geeks, states that &lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;a href="http://www-cs-faculty.stanford.edu/%7Eknuth/email.html" style="font-style: italic;"&gt;he has been a happy man&lt;/a&gt;&lt;span style="font-style: italic;"&gt; ever since January 1, 1990, when he no longer had an email address"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;C. G. Jung, not a big hacker himself, but still the father of &lt;a href="http://en.wikipedia.org/wiki/Analytical_psychology"&gt;analytical psychology&lt;/a&gt; (aptly, also known as "Jungian psychology"), has this to tell us in his autobiographical project "&lt;a href="http://en.wikipedia.org/wiki/Memories_dreams_reflections"&gt;Memories, Dreams, Reflections&lt;/a&gt;", in a chapter called "The Tower":&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Our souls, as well as our bodies, are composed of individual elements which were all already present in the ranks of our ancestors. The 'newness' in the individual psyche is an endlessly varied recombination of age-old components. Body and soul therefore have an intensely historical character, and find no proper place in what is new, in things that have just come into being. That is to say, our ancestral components are only partly at home in such things. We are very far from having finished completely with the Middle Ages, classical antiquity, and primitivity, as our modern psyches pretend. Nevertheless, we have plunged down a cataract of progress which sweeps us on into the future with ever wilder violence the farther it takes us from our roots. Once the past has been breached, it is usually annihilated, and there is no stopping the forward motion. But it is precisely the loss of connection with the past, our uprootedness, which has given rise to the 'discontents' of civilization and to such a flurry and haste that we live more in the future and its chimerical promises of a golden age than in the present, with which our whole evolutionary background has not yet caught up. We rush impetuously into novelty, driven by a mounting sense of insufficiency, dissatisfaction, and restlessness. We no longer live on what we have, but on promises, no longer in the light of the present day, but in the darkness of the future, which, we expect, will at last bring the proper sunrise. We refuse to recognize that everything better is purchased at the price of something worse; that, for example, the hope of greater freedom is canceled out by increased enslavement to the state, not to speak of the terrible perils to which the most brilliant discoveries of science expose us. The less we understand of what our fathers and forefathers sought, the less we understand ourselves, and thus we help with all our might rob the individual of his roots and his guiding instincts, so that he becomes a particle in the mass, ruled only by what Nietzsche called the spirit of gravity.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Reforms by advances, that is, by new methods or gadgets, are of course impressive at first, but in the long run they are dubious and in any case dearly paid for. They by no means increase the contentment or happiness of people on the whole. Mostly, they are deceptive sweetenings of existence, like speedier communications which unpleasantly accelerate the tempo of life, and leave us with less time than ever before. &lt;/span&gt;Omnis festinatio ex parte diaboli est&lt;span style="font-style: italic;"&gt; - all haste is of the devil, as the old masters used to say.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Reforms by retrogressions, on the other hand, are as a rule less expensive and in addition more lasting, for they return to the simpler, tried and tested ways of the past and make the sparsest use of newspapers, radio, television, and supposedly timesaving innovations."&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-97155719286850700?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/97155719286850700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=97155719286850700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/97155719286850700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/97155719286850700'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/10/gps-coordinates-of-jungs-tower.html' title='The GPS Coordinates of Jung&apos;s Tower'/><author><name>rc</name><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-9064003576220513352.post-5054765432560912393</id><published>2008-07-19T22:00:00.000-07:00</published><updated>2012-01-09T10:36:35.101-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>Code Reuse: It Would Be a Very Good Idea</title><content type='html'>As you must have noticed, the title of this article paraphrases a &lt;a href="http://en.wikipedia.org/wiki/Ghandi"&gt;Ghandi&lt;/a&gt; quote: When asked what he though of Western civilization, he famously replied &lt;span style="font-style: italic;"&gt;"I think it would be a very good idea"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Code reuse in the software industry is an elusive beast. Words such as &lt;span style="font-style: italic;"&gt;"reinventing the wheel"&lt;/span&gt; are often being paraded around by people across departments even remotely connected to computer programming, and everyone seems to be thoroughly convinced about the perils of re-writing code that's already been written, of solving problems that have already been solved.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Unless&lt;/span&gt;, we need to reuse code for &lt;span style="font-style: italic;"&gt;our project&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;It comes as no surprise to most seasoned software developers that &lt;span style="font-style: italic;"&gt;code reuse almost never happens&lt;/span&gt;. That is not to say they endorse the situation. But it's just a fact of life. Why? That's a tough question to answer.&lt;br /&gt;&lt;br /&gt;In today's fast-paced computer software industry, developers are being hired right out of highschool, or in their junior college years. They come from all possible backgrounds, and most of them have not properly studied their field for the full time required to master their tools. They tend to do whatever learning they can on the job, and then float towards management positions as soon as they've mastered enough to finally be able to be of proper use.&lt;br /&gt;&lt;br /&gt;A programming language such as C++ takes years to master. Add some time for learning how to use a control versioning system tool, some build tools, a couple of non-trivial source code editors, the quirks of a supporting OS, basic network administration, some APIs, and properly study a specific business domain, and you've got a good chunk of your life spent working to master your field. Garbage-collected, user-friendlier languages such as Java or C# take somewhat less time to learn, but still require considerable effort to master.&lt;br /&gt;&lt;br /&gt;To be able to reuse code properly one needs to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;have enough experience to know where the project will be going, and anticipate usable solutions. For example, your application might only need to be Linux-compatible now, but why not be able to compile it for FreeBSD in the future? Making that decision upfront will save development time in the future, while incurring little or no overhead in present development.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;know as many tools (programming languages, build tools, operating systems, UML tools, etc.) as possible, or at least know &lt;span style="font-style: italic;"&gt;about&lt;/span&gt; them, and be willing to properly study them if need arises.&lt;/li&gt;&lt;li&gt;anticipate maintenance costs, and project risks. For example, it might pay off to use a stable open-source library maintained by other people if your team cannot afford to maintain it's own custom version. Your team can find bugs and send patches to the maintainers anyway, so debugging is still possible, but the bulk of the work is done by somebody else. That way, you will also have the benefit of others' experience - all users will find bugs and send patches, so by the next version there'll be more bugs fixed than there would have been if you were the only library users. This approach also pays off if your team has little or no resources available for testing this piece of software - you'll be testing it a bit by using it, and so will it's other users: all in all a lot more testing than you alone could have done.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;have an open mind and realistic expectations about your team's competency level and schedule. This is usually very hard to do. The line of thinking is usually "we are very competent, we intimately know the project, and custom code is the best, and we don't need all that bloat that somebody else's library will bring into the project". Sometimes, that is indeed the case, but for a huge percent of projects that's a trap. We soon discover that "that bloat" was there for good reason, and now we either need to switch to that implementation, or write our own "bloat". Obviously, &lt;span style="font-style: italic;"&gt;your&lt;/span&gt; team &lt;span style="font-style: italic;"&gt;really is&lt;/span&gt; the best - you're in the former category. Just keep this guideline in mind for your next job, though...&lt;/li&gt;&lt;/ol&gt;The conclusion? It almost &lt;span style="font-style: italic;"&gt;always pays off&lt;/span&gt; to reuse code. &lt;span style="font-style: italic;"&gt;Not only from your company&lt;/span&gt; (not reusing company code is only excusable if it's very bad code, and then that's a lame excuse). Find a mature product, find out what types of support it offers (forums, mailing lists, live technical support, knowledge bases, etc.), and start using it. You'll roll out your software on budget and on schedule, you'll avoid grunt work, you'll make your users happy, you'll make the library authors happy, and you'll make yourself happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-5054765432560912393?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/5054765432560912393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=5054765432560912393' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/5054765432560912393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/5054765432560912393'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/07/code-reuse-it-would-be-very-good-idea.html' title='Code Reuse: It Would Be a Very Good Idea'/><author><name>rc</name><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-9064003576220513352.post-8919160469041147031</id><published>2008-07-03T03:43:00.000-07:00</published><updated>2008-07-03T03:57:45.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><category scheme='http://www.blogger.com/atom/ns#' term='career'/><title type='text'>A Memetic View on Project Management</title><content type='html'>Having recently discovered &lt;a href="http://www.itee.uq.edu.au/%7Ejonw/"&gt;Jon Whitty&lt;/a&gt;, I've stumbled upon &lt;a href="http://espace.library.uq.edu.au/eserv.php?pid=UQ:13418&amp;amp;dsID=_THE_PM_BOK_CODE.pdf"&gt;his critique of project management&lt;/a&gt;, with reference to the &lt;a href="http://en.wikipedia.org/wiki/Project_Management_Body_of_Knowledge"&gt;PMBoK&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"This paper makes no claim of uncovering a secret or hidden message, but it does profess to decipher the memetic code of project management (PM) to reveal the real reason why PM is so prevalent.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Why is PM so prevalent? Even though the discipline of PM is ubiquitous in Western society it exhibits many inexplicable and contradictory aspects. The prevalence of PM continues to increase across all business sectors and all geographical regions, with companies suggesting that projects are a vital contributor to future business success, and that projects are the key enabler of business change. PM is also consuming more of corporate training budgets than ever before. An increasing amount of &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Universities are also delivering PM courses at undergraduate and postgraduate level, and at least one corporation is supporting the teaching of PM at high-schools. The bulk of such training and teaching is modeled on the Project Management Institute (PMI®) Guide to the Project ManagementBody of Knowledge (PMBOK Guide).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;However, despite the prevalence of PM, organizations report that project failure is commonplace and that the delivery of projects to cost, time and benefits is not improving. It is therefore valid to ask why PM is so widely and commonly occurring, accepted, and practiced, when it still fails to live up to expectations."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Whether the gentleman is right or not, I will not venture to say. What I will say, is this: his answer will certainly surprise you, and most likely completely change the way you've been thinking about the issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-8919160469041147031?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/8919160469041147031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=8919160469041147031' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/8919160469041147031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/8919160469041147031'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/07/memetic-view-on-project-management.html' title='A Memetic View on Project Management'/><author><name>rc</name><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-9064003576220513352.post-1207786502069568435</id><published>2008-06-25T06:45:00.000-07:00</published><updated>2012-01-09T10:43:24.277-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software implementation'/><title type='text'>C++ System Programming Rule: Always Join() Threads Referencing External Objects</title><content type='html'>Let's assume you want to instantiate an object of type &lt;span style="font-style: italic;"&gt;C&lt;/span&gt; in function &lt;span style="font-style: italic;"&gt;f()&lt;/span&gt;. Function &lt;span style="font-style: italic;"&gt;f()&lt;/span&gt; then proceeds to create a new thread, and passes a reference to this object to the new thread. The new thread uses the object, and then exits, but &lt;span style="font-style: italic;"&gt;f()&lt;/span&gt; &lt;span style="font-style: italic;"&gt;does not&lt;/span&gt; &lt;span style="font-style: italic;"&gt;join()&lt;/span&gt; the new thread (that is, it does not wait and make sure that the new thread has finished running before &lt;span style="font-style: italic;"&gt;f()&lt;/span&gt; itself exits). A snippet of pseudocode is worth a thousand words:&lt;br /&gt;&lt;pre&gt;void thread_fn(const C&amp;amp; c)&lt;br /&gt;{&lt;br /&gt;  c.perform();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void f()&lt;br /&gt;{&lt;br /&gt;  C c;&lt;br /&gt;  system::create_thread(thread_fn, c);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Creating a thread and then not caring about when it stops seems to especially make sense with UNIX &lt;a href="https://computing.llnl.gov/tutorials/pthreads/#Joining"&gt;detached threads&lt;/a&gt;. But &lt;span style="font-style: italic;"&gt;it almost never makes sense to use detached threads with C++&lt;/span&gt;. Because &lt;span style="font-style: italic;"&gt;C++ programs tend to use objects&lt;/span&gt;. And &lt;span style="font-style: italic;"&gt;C++ objects get destroyed&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Let's consider the following scenario:&lt;br /&gt;&lt;br /&gt;1. &lt;span style="font-style: italic;"&gt;F()&lt;/span&gt; creates the &lt;span style="font-style: italic;"&gt;C&lt;/span&gt; instance &lt;span style="font-style: italic;"&gt;c&lt;/span&gt;. &lt;span style="font-style: italic;"&gt;F()&lt;/span&gt; then proceeds to create a new thread with the fictional &lt;span style="font-style: italic;"&gt;system::create_thread()&lt;/span&gt; function. We will assume that this call also starts the new thread, and it runs the &lt;span style="font-style: italic;"&gt;thread_fn()&lt;/span&gt; function in the new thread.&lt;br /&gt;&lt;br /&gt;2. &lt;span style="font-style: italic;"&gt;System::create_thread()&lt;/span&gt; has now exited. The new thread has been created, but &lt;span style="font-style: italic;"&gt;thread_fn()&lt;/span&gt; is not yet running in this new thread. &lt;span style="font-style: italic;"&gt;F()&lt;/span&gt; then exits, and in doing so destroys the &lt;span style="font-style: italic;"&gt;C&lt;/span&gt; instance, &lt;span style="font-style: italic;"&gt;c&lt;/span&gt;, the object that had been passed-by-reference to the new thread function.&lt;br /&gt;&lt;br /&gt;3. &lt;span style="font-style: italic;"&gt;Thread_fn()&lt;/span&gt; starts running, but it now has a reference to a destroyed object.&lt;br /&gt;&lt;br /&gt;What's the consequence of this? The program will abort. If &lt;span style="font-style: italic;"&gt;perform()&lt;/span&gt; is a virtual member function of &lt;span style="font-style: italic;"&gt;C&lt;/span&gt;, your program will most likely abort with an error along the lines of "&lt;span style="font-style: italic;"&gt;pure virtual function call&lt;/span&gt;". That is actually what happens most of the time, and I've seen many senior developers scratching their heads in disbelief at the possibility of having had been able to instantiate a C++ abstract base class, which is what the problem appears to be at first sight.&lt;br /&gt;&lt;br /&gt;So remember, &lt;span style="font-style: italic;"&gt;join()&lt;/span&gt; is your friend. Do not allow your main thread to exit until you've &lt;span style="font-style: italic;"&gt;join()&lt;/span&gt;ed all of the threads it has created. It's actually a good rule of thumb, regardless of the programming language you're using, but it especially applies to C++, where stack objects get destroyed when they go out of scope.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-1207786502069568435?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/1207786502069568435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=1207786502069568435' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/1207786502069568435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/1207786502069568435'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/06/c-system-programming-rule-always-join.html' title='C++ System Programming Rule: Always Join() Threads Referencing External Objects'/><author><name>rc</name><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-9064003576220513352.post-4771119533421960970</id><published>2008-06-13T06:11:00.000-07:00</published><updated>2012-01-09T11:00:11.459-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><category scheme='http://www.blogger.com/atom/ns#' term='career'/><title type='text'>Open Source vs. Closed Source Projects: A Career Choice</title><content type='html'>Open source does not necessarily mean free software. My favourite CORBA ORB, &lt;a href="http://www.orbacus.com/"&gt;Orbacus&lt;/a&gt;, is not free, but it's open source - that is, you also get the source code with the precompiled stuff. Conversely, &lt;a href="http://www.praven3.com/credit/"&gt;CREdit&lt;/a&gt;, a lightweight, highly customizable text editor, is free software, but you can't get the source code for it.&lt;br /&gt;&lt;br /&gt;Also, free or open source software doesn't mean that the people working on the project don't get paid. There are many complex ways of generating revenue.&lt;br /&gt;&lt;br /&gt;Here's the case for working on open source software:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;it will improve your skills as a software craftsperson. It's widely known that we perform better when we know that our peers are watching our work. Therefore, we write better code knowing that your peers will actually see and critique it. With more people watching, you also get more bug reports and patches.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;there's personal visibility. With most closed source companies, your contribution will be the work of "&amp;lt;insert your company name here&amp;gt; &amp;lt;insert your project name here&amp;gt; team". An open source project more often than not provides some way of name-recognition for its contributors.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;you will make contacts within the community, thus creating opportunities for meaningful future work, hopefully even skipping repetitive, boring steps such as job interviews (since your competency has already been proven - everyone has access to the details of your work).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;companies are sold, become bankrupt, or simply decide to shut down whole departments. License permitting, an open source project can continue it's life even after the original maintainers move on, so you'll be more likely to be able to continue your work if you're so inclined.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-4771119533421960970?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/4771119533421960970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=4771119533421960970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/4771119533421960970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/4771119533421960970'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/06/open-source-vs-closed-source-projects.html' title='Open Source vs. Closed Source Projects: A Career Choice'/><author><name>rc</name><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-9064003576220513352.post-7893728272018108897</id><published>2008-05-29T00:20:00.000-07:00</published><updated>2012-01-09T11:02:52.693-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software implementation'/><title type='text'>C/C++ System Programming Rule: If You Must Write Single-Threaded Network Servers, Always Prefer Poll() to Select()</title><content type='html'>Let's assume you're going to write a C/C++ network server application, and you need to decide how to implement the code responsible for accepting connections from clients, and serving the clients simultaneously after accepting the request. Typically, you'd do this in one of two ways:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Write a multithreaded application, with one dedicated thread blocking in accept(). Once a connection has been established, take the new client socket handle, pass it to a worker thread and resume waiting for a new connection in accept().&lt;/li&gt;&lt;li&gt;Use a single thread for accept()ing and processing client requests. If you'll look this method up, you'll find that most examples illustrate &lt;a href="http://www.lowtek.com/sockets/select.html"&gt;using select()&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;While conceptually there's nothing wrong with using select(), there's a serious problem with it's implementation that makes it unsuitable for real-world server applications that need to scale well. The problem is this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Macro: int FD_SETSIZE&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;    The value of this macro is &lt;/span&gt;the maximum number of file descriptors that a fd_set object can hold information about&lt;span style="font-style: italic;"&gt;. On systems with a fixed maximum number, FD_SETSIZE is at least that number. &lt;/span&gt;On some systems, including GNU, there is no absolute limit on the number of descriptors open, but this macro still has a constant value which controls the number of bits in an fd_set&lt;span style="font-style: italic;"&gt;;  &lt;/span&gt;if you get a file descriptor with a value as high as FD_SETSIZE, you cannot put that descriptor into an fd_set&lt;span style="font-style: italic;"&gt;."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On my Slackware Linux system, FD_SETSIZE is #defined as 1024 in /usr/include/bits/typesizes.h. BUT, it's plausible that your application might want to be able to handle more than 1024 socket descriptors at one time. And once you get socket descriptor number 1025, put it in your fd_set and give that to select(), &lt;span style="font-style: italic;"&gt;all bets are off&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Some systems will do the right thing if you #define your own FD_SETSIZE, but that's not crossplatform, and even worse, it's very error-prone. What about libraries you might be linking against, that have already been compiled using the default FD_SETSIZE value?&lt;br /&gt;&lt;br /&gt;You might think that an application with more than 1024 sockets opened at the same time is probably not a good idea, and you'd probably be right. However, you don't even need to have more than 1024 socket handles active simultaneously. All you need to do to get to "there be dragons" territory is to have &lt;span style="font-style: italic;"&gt;one socket handle with the value 1025&lt;/span&gt; and try to use that in a select() fd_set.&lt;br /&gt;&lt;br /&gt;The alternative? Meet your new friend &lt;a href="http://www.opengroup.org/onlinepubs/000095399/functions/poll.html"&gt;poll()&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-7893728272018108897?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/7893728272018108897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=7893728272018108897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/7893728272018108897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/7893728272018108897'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/cc-system-programming-rule-if-you-must.html' title='C/C++ System Programming Rule: If You Must Write Single-Threaded Network Servers, Always Prefer Poll() to Select()'/><author><name>rc</name><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-9064003576220513352.post-3978403262107217171</id><published>2008-05-18T03:57:00.000-07:00</published><updated>2012-01-10T03:14:10.532-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>Efficient Thread Pool Design</title><content type='html'>If you've ever needed to design a non-trivial network server, you've probably needed your application to be able to handle requests as quickly as they come. Leaving aside the old "threads versus processes" UNIX debate (threads are better if you need efficiency and portability outside the fork() realm, processes are better for high risk workers where one crashed worker won't bring the whole application down), and assuming we've chosen threads, we now have two choices:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create new threads on demand. That is, once a new connection to our server is initiated, start a new thread and assign it the required task. This approach works best where either the server will have considerable idle time (in which case it won't need to waste unused thread handles), or where the instructions needed to create the new thread take much less CPU time than the actual "business" code.&lt;/li&gt;&lt;li&gt;Create a thread pool. At application initialization time, create all the threads you think you will need. Thus, the thread creation/start code will only run once. After that, all the threads will wait for requests to handle. That way, once a request comes, it will be handled in the fastest manner possible. Another advantage of this approach is that we'll know upfront if the system can handle all the threads we think might be running simultaneously at any given time (something similar to &lt;a href="http://www.gotw.ca/publications/mill16.htm"&gt;Herb Sutter&lt;/a&gt;'s suggested strategy for dealing with &lt;span style="font-style: italic;"&gt;std::operator new&lt;/span&gt;'s &lt;span style="font-style: italic;"&gt;std::bad_alloc&lt;/span&gt; exception handling - just allocate and touch all the memory you think you're going to need upfront and use that pool for your application).&lt;/li&gt;&lt;/ol&gt;Now, assuming we've decided to use a thread pool, the first solution that we usually think of is &lt;span style="font-style: italic;"&gt;"the queue solution"&lt;/span&gt;. The queue solution goes something like this (pseudocode):&lt;br /&gt;&lt;pre&gt;// Main thread:&lt;br /&gt;&lt;br /&gt;while(keepAcceptingConnections) {&lt;br /&gt; socket request = server_.accept();&lt;br /&gt;&lt;br /&gt; requestQueueMutex_.lock();&lt;br /&gt; requestQueue_.push(request);&lt;br /&gt; requestQueueMutex_.unlock();&lt;br /&gt;&lt;br /&gt; requestQueueSemaphore_.post();&lt;br /&gt;&lt;br /&gt; // if error, set keepAcceptingConnections, etc.&lt;br /&gt;}&lt;/pre&gt;You'll notice that what we need to use is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A mutex, needed to synchronize read/write access to the request queue.&lt;/li&gt;&lt;li&gt;A request queue. This is where you usually put the sockets returned from accept().&lt;/li&gt;&lt;li&gt;A semaphore, needed to signal to the worker threads that there's one more request for them waiting in the queue.&lt;/li&gt;&lt;/ol&gt;Here's how you might write a worker thread:&lt;br /&gt;&lt;pre&gt;// Worker thread:&lt;br /&gt;&lt;br /&gt;while(keepRunning) {&lt;br /&gt; requestQueueSemaphore_.wait();&lt;br /&gt;&lt;br /&gt; requestQueueMutex_.lock();&lt;br /&gt; socket request = requestQueue_.pop();&lt;br /&gt; requestQueueMutex_.unlock();&lt;br /&gt;&lt;br /&gt; // Do actual work with the request socket,&lt;br /&gt; // set keepRunning, etc.&lt;br /&gt;}&lt;/pre&gt;That's the time-honoured, and the simplest, design for a thread pool. BUT, there's something better. It's called &lt;a href="http://www.kircher-schwanninger.de/michael/publications/lf.pdf"&gt;the leader/follower pattern&lt;/a&gt;, and it eliminates the need for the requests queue, the semaphore, and separate implementation for a main and worker threads.&lt;br /&gt;&lt;br /&gt;What the pattern proposes, is that there be only one thread type (no longer a main thread and a worker thread design), but that this thread go through several states. That is, a thread in the thread pool can be in the "&lt;span style="font-style: italic;"&gt;leader state&lt;/span&gt;" at one time, and the "&lt;span style="font-style: italic;"&gt;follower state&lt;/span&gt;" at another. &lt;span style="font-style: italic;"&gt;Only one thread can be a leader&lt;/span&gt; at one given moment, but &lt;span style="font-style: italic;"&gt;we can have more follower (or worker) threads running&lt;/span&gt; simultaneously. If I've managed to confuse you, the following pseudocode snippet will make it all clearer:&lt;br /&gt;&lt;pre&gt;// Leader/follower thread:&lt;br /&gt;&lt;br /&gt;while(keepAcceptingConnections &amp;amp;&amp;amp; keepRunning) {&lt;br /&gt; // Follower state:&lt;br /&gt; serverSocketMutex_.lock();&lt;br /&gt;&lt;br /&gt; // Leader state:&lt;br /&gt; socket request = server_.accept();&lt;br /&gt; serverSocketMutex_.unlock();&lt;br /&gt;&lt;br /&gt; // Follower state:&lt;br /&gt; // ... do actual work with request here&lt;br /&gt;}&lt;/pre&gt;So, no more queue, no more semaphore. As soon as a request comes, the thread simply starts handling it, and unlocks the mutex controlling the accept() for the next thread available for entry into the "leader" block of code. If all threads are busy, there's no accept() in progress, so the number of acceptable requests is always equal to the number of available idle threads.&lt;br /&gt;&lt;br /&gt;It can, and often does, get more complex than that, but that's the gist of it. For a more in-depth analysis of the subject, refer to &lt;a href="http://www.kircher-schwanninger.de/michael/publications/lf.pdf"&gt;the full paper&lt;/a&gt; by Douglas Schmidt and Carlos O'Ryan.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-3978403262107217171?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/3978403262107217171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=3978403262107217171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/3978403262107217171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/3978403262107217171'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/efficient-thread-pool-design.html' title='Efficient Thread Pool Design'/><author><name>rc</name><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-9064003576220513352.post-847143297699426524</id><published>2008-05-13T23:35:00.000-07:00</published><updated>2012-01-10T02:46:53.034-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software implementation'/><category scheme='http://www.blogger.com/atom/ns#' term='creativity'/><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><title type='text'>Debugging When the Debugger Can't Help</title><content type='html'>I've recently had a discussion with a couple of friends about exceptional cases where an application crashes, but the debugger is completely off-mark about the place that causes the problem.&lt;br /&gt;&lt;br /&gt;As an example (and in keeping with UNIX-style examples), consider an application that produces a &lt;span style="font-style: italic;"&gt;core&lt;/span&gt; file, and it's compiled in &lt;span style="font-style: italic;"&gt;debug mode&lt;/span&gt; (-O0 -g). &lt;span style="font-style: italic;"&gt;But&lt;/span&gt;, when we load the application file and the core file in gdb, and try to obtain a backtrace, we end up in some perfectly innocent std::string member function call.&lt;br /&gt;That can't possibly be it, so after a few hours of debugging something dawns on us: could it be that &lt;span style="font-style: italic;"&gt;gdb is wrong&lt;/span&gt;? Well, technically speaking, no, it can't. But the core file is irrelevant.&lt;br /&gt;&lt;br /&gt;Why? Well, most of the time that happens because of what's generally referred to as "a double-free" issue. In C++ terms, that tends to happen when a smart pointer class doesn't have well-thought-out copy semantics, and two smart pointer instances end up pointing at the same memory address via their identical underlying dumb pointers. When the first smart pointer gets destroyed, it calls "delete p_;", then the second smart pointer gets destroyed and does the same thing, for the same value of "p_".&lt;br /&gt;&lt;br /&gt;But it doesn't need to be a pointer. Closing the same file handle, or socket handle, or mutex handle twice can have the same effect. Basically, anything you can think of as a resource that you acquire, and then need to release, can get you in this fix.&lt;br /&gt;&lt;br /&gt;At other times, invalid debugging information is caused by invalid memory access: buffer overflows, interpreting garbage data as valid objects, and so on.&lt;br /&gt;&lt;br /&gt;There's no easy way out. You can of course set breakpoints and watchpoints, but you'll soon discover they won't be very helpful. You need to be able to pinpoint the exact moment when something went wrong - if you're one tiny step after it happens you're too late. The call stack breaks and you stop getting useful information.&lt;br /&gt;&lt;br /&gt;Here are a few suggestions that might help you cope with the problem:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Have you recently added a new library to your project? Does it seem likely that the crash is caused by a call to a function in that library?&lt;/li&gt;&lt;li&gt;Have you (or someone in your team) modified any particular code recently? Can you revert your build to the previous version (in case the previous version was working)? Can you see the differences between the two versions (with CVS, for example, you can use the &lt;a href="http://cervisia.kde.org/"&gt;Cervisia&lt;/a&gt; tool for this task)?&lt;/li&gt;&lt;li&gt;Have a TRACE(x) macro in your C/C++ project. It should expand to nothing at all in release-mode, but print it's argument to a file in debug mode. Feel free to sprinkle as many TRACE() calls as you wish throughout your code. Read the output after the crash. What was the last thing that in the trace file before the crash? Start commenting out blocks of code while the crash still happens, until you find the line of code that has caused it. (For C++ users, a special case of TRACE() is, for lack of a better name, SCOPE_TRACE(): output the name of the current function and line, in a special stack object's constructor and destructor - this is an exception-safe way to know when you've both entered and left a function.)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-847143297699426524?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/847143297699426524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=847143297699426524' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/847143297699426524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/847143297699426524'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/debugging-when-debugger-cant-help.html' title='Debugging When the Debugger Can&apos;t Help'/><author><name>rc</name><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-9064003576220513352.post-4033564875534912664</id><published>2008-05-08T23:28:00.000-07:00</published><updated>2012-01-10T03:06:35.693-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>Automatic Coding Style Enforcement</title><content type='html'>How often did it happen to you that your team has decided on a coding style, somebody wrote a document about it, and it all seemed great until you've checked out a source code file that a new colleague wrote, only to find out that he/she had used tabs instead of spaces for indentation, and that his/her 8-characters tab indents don't look that hot with your 4-spaces indents?&lt;br /&gt;&lt;br /&gt;Having a coding style document is important, and enforcing it will prove very valuable in time. And indeed, some coding style constraints cannot be enforced any other way, except having someone periodically reading the others' code and requesting changes. This is, in part, due to the somewhat flexible definition of what a coding style document is (for example, some stop after defining "the look" of source code: indentation rules, naming conventions, etc.; while others include best-practices rules such as "never use naked pointers" - for a good (and free) book of the latter type, see &lt;a href="http://hem.passagen.se/erinyq/industrial/"&gt;"Industrial Strength C++"&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;But&lt;/span&gt;, some things &lt;span style="font-style: italic;"&gt;can&lt;/span&gt; be transparently enforced. That is, if your favourite editor supports that. The top editors on my list, (X)Emacs and Vim, both do. You can set the number of spaces you'll see for a tab indent, you can specify whether or not pressing the tab key will translate to any number of spaces, and you can tell the editor to interpret the file as source code written in a specific programming language (for syntax highlighting purposes, when it can't be deduced based on file extension).&lt;br /&gt;&lt;br /&gt;This (or variations of it) is what you'll find at the bottom of all the source code files of most of my projects:&lt;br /&gt;&lt;pre&gt;/*&lt;br /&gt;  Local Variables:&lt;br /&gt;  mode: c++&lt;br /&gt;  c-basic-offset: 8&lt;br /&gt;  tab-width: 8&lt;br /&gt;  c-indent-comments-syntactically-p: t&lt;br /&gt;  c-tab-always-indent: t&lt;br /&gt;  indent-tabs-mode: t&lt;br /&gt;  End:&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;// vim:shiftwidth=8:autoindent:tabstop=8:noexpandtab:softtabstop=8&lt;/pre&gt;Now any team member who edits the file with (X)Emacs or Vim will have the editor enforce coding style conventions, whether (s)he forgot them or not.&lt;br /&gt;Find out if your favourite editor can help out like that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-4033564875534912664?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/4033564875534912664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=4033564875534912664' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/4033564875534912664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/4033564875534912664'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/automatic-coding-style-enforcement.html' title='Automatic Coding Style Enforcement'/><author><name>rc</name><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-9064003576220513352.post-7465011441124809777</id><published>2008-05-07T21:52:00.000-07:00</published><updated>2012-01-10T04:13:00.112-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='creativity'/><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>The Most Helpful Kind of Knowledge in Software Architecture</title><content type='html'>Many people argue that computer programming depends heavily on mathematics. To some degree, that's true - it is a fair assumption that the computer model is &lt;a href="http://en.wikipedia.org/wiki/Turing_machine"&gt;a mathematical abstraction&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;But programming involves &lt;a href="http://en.wikipedia.org/wiki/Meaning_is_use#Language.2C_meaning.2C_and_use"&gt;&lt;i&gt;using&lt;/i&gt;&lt;/a&gt; a &lt;span style="font-style: italic;"&gt;programming language&lt;/span&gt;. Unless that programming language contains the particle "math" somewhere in it's name (and perhaps even then), the emphasis, for the purposes of this article, should be on the word &lt;i&gt;"language"&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;What language has been used for for thousands of years is to express our understanding of the world. You can use language to write poetry, you can swear, and you can write technical manuals. Some early languages were nounless - what you can express today is different than what you could express back then.&lt;br /&gt;&lt;br /&gt;Languages are evolving entities. We add new words as the need presents itself. The ancients did not have &lt;span style="font-style: italic;"&gt;LCD monitors&lt;/span&gt;. They did not have to &lt;span style="font-style: italic;"&gt;implement quick sort&lt;/span&gt;. Part of mankind's development has been to add new objects to its conceptual toolbox, and remove obsolete ones.&lt;br /&gt;&lt;br /&gt;Adding new concepts is a difficult business, and we need to take into account a couple of things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Our building blocks&lt;/span&gt;. The context. The existing concepts, that are the basis of the new ones. With the addition of a new concept, the context changes and the loop continues.&lt;span style="font-style: italic;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The need for the birth of new concept (quantifiable perhaps by the intuitiveness of the use of the new concept)&lt;/span&gt;. We don't go around thinking that something's missing in the world because nobody invented sunglasses that produce bread.&lt;/li&gt;&lt;/ol&gt;Does anything sound familiar so far? If you're designing code, it should. It's basically software architecture: the context is&lt;span style="font-style: italic;"&gt; your programming language &lt;/span&gt;(classes, overridables, data encapsulation, functions, operator overloading, data manipulation primitives, etc.) and &lt;span style="font-style: italic;"&gt;your dependencies&lt;/span&gt; (libraries you need to use, and their design and implementation). The new concepts collaborate to make your code work (in object-oriented terms, these will be classes and class hierarchies). The quality of these concepts, all other things being equal, will always depend on the quality of your training in ontology.&lt;br /&gt;&lt;br /&gt;In conclusion, good to have attributes for a software designer would be:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Time in the trenches with the category of programming language that the project will use&lt;/span&gt; (for example, C++ or Java for object-oriented software development, C for procedural software development, and so on). You will simply not understand the full power of the tools you're supposed to map your high-level concepts on, unless you're experienced with them.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Experience with as many other frameworks as possible&lt;/span&gt;. They're brainchildren of other designers. Some of them are very valuable. Especially at the beginning, emulation is nothing to be ashamed of ("imitate good writing").&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;To be well read&lt;/span&gt;. While books on the Rational Unified Process, Agile methodology, and so on, do have their value, the recommendation here is to go deeper into language semantics, ontology, phenomenology and deconstruction, as written about by&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Wittgenstein"&gt;Wittgenstein&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Heidegger"&gt;Heidegger&lt;/a&gt;. To the extent that designing a new system is an exercise in ontology and semantics, there's nothing better than turning to the real professionals of that field.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-7465011441124809777?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/7465011441124809777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=7465011441124809777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/7465011441124809777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/7465011441124809777'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/most-helpful-kind-of-knowledge-in.html' title='The Most Helpful Kind of Knowledge in Software Architecture'/><author><name>rc</name><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-9064003576220513352.post-995310622500955735</id><published>2008-05-06T08:31:00.000-07:00</published><updated>2012-01-10T03:20:53.446-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software implementation'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>C/C++ Rule: Never Locally Release a Resource Allocated in a Dynamically Loaded Plugin</title><content type='html'>This rule especially applies to acquired memory, but it extends to file or mutex handles, and pretty much anything that can be considered a transient resource.&lt;br /&gt;&lt;br /&gt;After you load a module (an .so for UNIX - with &lt;i&gt;dlopen()&lt;/i&gt;, or a .dll for MS Windows - with &lt;i&gt;LoadLibrary()&lt;/i&gt;), you might call a function that returns a pointer to freshly allocated memory.&lt;br /&gt;&lt;br /&gt;Example pseudocode:&lt;br /&gt;&lt;pre&gt;typedef char* (*p_aq_fn)();&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    void *module_handle = &lt;br /&gt;        dlopen("mymodule.so", ...);&lt;br /&gt;&lt;br /&gt;    if(module_handle) {&lt;br /&gt;        p_aq_fn heap_allocated_string = &lt;br /&gt;                 (p_aq_fn)dlsym(module_handle,&lt;br /&gt;                             "heap_allocated_string");&lt;br /&gt;        if(heap_allocated_string) {&lt;br /&gt;            char *my_string = &lt;br /&gt;                heap_allocated_string();&lt;br /&gt;            // Use my_string&lt;br /&gt;            free(my_string);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if(module_handle)&lt;br /&gt;       dlclose(module_handle);     &lt;br /&gt;&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;/pre&gt;Yes, the code is not exception safe, or very of C++, for that matter, but please ignore that for the bigger picture I'm trying to paint: &lt;span style="font-style: italic;"&gt;the free(my_string) call is asking for trouble&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The reason why that won't work is this: &lt;span style="font-style: italic;"&gt;dynamically loaded plugins have their own memory and exception handlers&lt;/span&gt;. It is therefore a very bad idea to allocate memory using one allocator, and ask another allocator to release it. I repeat: &lt;span style="font-style: italic;"&gt;the allocator used by the loaded module is not the same as the  allocator used by the module's loader&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Don't despair though, there is a solution to this problem: for each type of resource that you plan to acquire from the module, provide a module function responsible for releasing it. Then get a handle to that function, and use it to release your resource once you're done with it. Such as:&lt;br /&gt;&lt;pre&gt;typedef void (*p_release_fn)(char *);&lt;br /&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;p_release_fn release_string = &lt;br /&gt;    (p_release_fn)dlsym(module_handle,&lt;br /&gt;                        "release_string");&lt;br /&gt;if(!release_string)&lt;br /&gt;    ERROR("No release_string symbol!");&lt;br /&gt;&lt;br /&gt;// Use heap allocated my_string here&lt;br /&gt;&lt;br /&gt;release_string(my_string);&lt;/pre&gt;&lt;span style="font-style: italic;"&gt;NOTE&lt;/span&gt;: You should, of course, use RAII (resource acquisition is initialization) to make your code exception-safe if you're planning on using C++. In spite of it's fancy name, meant to scare away nice people from potentially lucrative software development careers, all that it means is that you should implement special classes whose instances will acquire resources in their constructors and release them in their destructors (be very careful about copy semantics!), and use them as stack objects in the scope that uses the resources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-995310622500955735?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/995310622500955735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=995310622500955735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/995310622500955735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/995310622500955735'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/cc-rule-never-locally-release-resource.html' title='C/C++ Rule: Never Locally Release a Resource Allocated in a Dynamically Loaded Plugin'/><author><name>rc</name><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-9064003576220513352.post-970159062029665859</id><published>2008-05-06T02:13:00.000-07:00</published><updated>2012-01-10T03:43:27.693-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='distributed computing'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>CORBA Myths and Facts</title><content type='html'>I'm sometimes asked to diagnose problems in complex distributed projects that have become hard to continue or maintain. In a significant percent of cases, CORBA would have saved the day had it been used from the start.&lt;br /&gt;&lt;br /&gt;When asked about their decision &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; to use CORBA, the decision makers usually invoke these arguments:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CORBA is too complex&lt;/span&gt;. The irony is that often the project developers implement (at the very least) their own skeleton/stub functionality, something that could have been avoided by simply defining a 10-line CORBA IDL interface, running the idl-to-source-code compiler, and simply derive a class that implements the business-logic. At it's simplest, CORBA is a quick (and fun) way to implement distributed binary objects across potentially heterogeneous networks, with no more overhead than linking with the ORB library. &lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CORBA's IIOP protocol is sub-optimal&lt;/span&gt;. In fact, it is not. It's safe (and if you roll your own communication protocol you need to implement it with safety in mind, and test it for little things - such as potential DOS attacks, buffer overflows when serializing strings, etc.), and it's a binary protocol, which makes it "faster" and more compact than, say, SOAP's XML-based protocol. Furthermore, most ORBs will let you roll your own communication protocol, if IIOP is not to your liking.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;We've considered using CORBA, but the ORB software we've selected costs a lot of money&lt;/span&gt;. Some do. There are many free ORBs out there (MICO, TAO+ACE, etc.), but it's possible that they did not meet your needs. However, you need to ask yourself this: are you willing to pay a team of developers and a team of testers to re-implement basic CORBA functionality, for at least a couple of months (probably more, if you're not one of those companies that not only claims, but also does work with the top 5% people in the business)? If so, would that cost more than one ORB license right now? Because, in the end, if you do implement most of what an ORB offers even at it's simplest, I can guarantee that your solution will be inferior. A bold statement, perhaps, I stand by it. CORBA is a standard developed by a committee that includes top software companies and talented individuals; ORB software that's been around for many years and used by many software projects is bound to have benefited from more testing and improvements, and is bound to be more robust than your ad-hoc, in-house marshalling solution.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;We've compared CORBA to RMI/RPC/SOAP and the alternatives seem better&lt;/span&gt;. If you &lt;span style="font-style: italic;"&gt;don't actually need CORBA&lt;/span&gt; at all, then by all means &lt;span style="font-style: italic;"&gt;do not use it&lt;/span&gt;. There really are cases where all you need is a socket and a bunch of bytes to push along. But &lt;span style="font-style: italic;"&gt;do not compare&lt;/span&gt; CORBA with RPC. You might compare &lt;i&gt;a subset&lt;/i&gt; of CORBA to RPC: the part that allows you to specify interfaces and marshall inter-process data. Even so, CORBA is an object-oriented technology that maps better on programming languages such as C++ or Java, and RPC is not that portable. &lt;span style="font-style: italic;"&gt;But&lt;/span&gt;, CORBA is &lt;span style="font-style: italic;"&gt;much more&lt;/span&gt; than language-independent interface specification and cross-platform data-marshalling. It also comes with it's own "standard library" of goodies. Things like the Naming Service, that maps a human-readable name to an interoperable object reference (IOR), or the Event Service, that allows you to request and use an event-channel, for real-time notifications from event providers to subscribers.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;But I don't need all that CORBA has to offer for my project. My own simple protocol is enough&lt;/span&gt;. Fair enough. But that may be right for today. You need to plan for tomorrow, so that when it comes you don't need to hire ten more developers and a consultant to sort out the mess. Ask yourself, "what will I do if my product is successful?". That would mean more and more users for your product - some of them will require new features.&lt;current+1&gt; &lt;span style="font-style: italic;"&gt;You&lt;/span&gt; will probably want to add more features and charge accordingly, to increase profit. Is it worth it to risk that trouble, when it doesn't even cost much extra to use something &lt;/current+1&gt;&lt;span style="font-style: italic;"&gt;now&lt;/span&gt; &lt;current+1&gt;that will make development and maintenance easier in the future? At most, it will cost you the price of the ORB (unless you use a free one), and the training time for your developers.&lt;/current+1&gt;&lt;/li&gt;&lt;/ol&gt;If I've managed to convince you to take a closer look before making that decision, I warmly recommend for further reading "&lt;a href="http://www.ciaranmchale.com/corba-explained-simply/"&gt;CORBA Explained Simply&lt;/a&gt;".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-970159062029665859?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/970159062029665859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=970159062029665859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/970159062029665859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/970159062029665859'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/corba-myths-and-facts.html' title='CORBA Myths and Facts'/><author><name>rc</name><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-9064003576220513352.post-8685751730208486141</id><published>2008-05-06T00:00:00.000-07:00</published><updated>2008-05-06T01:09:06.042-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software implementation'/><category scheme='http://www.blogger.com/atom/ns#' term='software  design'/><title type='text'>C++ Rule: You Can't Catch an Exception from Another Thread</title><content type='html'>C++ is an old language. It's got thousands of features and special cases, and by the time the ISO C++ standard was approved, there hadn't been enough time to include frequently used, but not core-important (at least not in the same way as, say, containers and iterators are core-important) concepts, such as sockets, and threads. Consequently, ISO C++ has no knowledge of threads (although Bjarne Stroustrup has said at the &lt;a href="http://pact07.cs.tamu.edu/"&gt;PACT 2007&lt;/a&gt; conference that they're acknowledging threads in the upcoming C++0x standard).&lt;br /&gt;&lt;br /&gt;What this means, is that when you're working with threads (perhaps implementing a threadpool with C++), you can't know what will happen if you mix exceptions-style context-switching with threads. It's &lt;span style="font-style: italic;"&gt;undefined&lt;/span&gt; behaviour, which means that it may, or it may not crash your computer, erase all of the files on your hard disk, or play the theme song from "&lt;a href="http://www.hbo.com/conchords/"&gt;Flight of the Conchords&lt;/a&gt;". Most likely, it will just crash your application.&lt;br /&gt;&lt;br /&gt;More to the point, you can't do &lt;span style="font-style: italic;"&gt;this&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;void thread_function(int *return_code)&lt;br /&gt;{&lt;br /&gt;   *return_code = NO_ERROR;&lt;br /&gt;&lt;br /&gt;   if(something_wrong)&lt;br /&gt;       throw MyException;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   try {&lt;br /&gt;       start_thread(thread_function);&lt;br /&gt;&lt;br /&gt;   } catch(const MyException&amp;amp;) {&lt;br /&gt;       log("Exception caught!");&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Or rather, you &lt;span style="font-style: italic;"&gt;can&lt;/span&gt; do it, but you'll most likely never get to the log() call. The exception thrown from the new thread will never be caught anywhere, and your program will misteriously abort. The proper way of doing it, would be something along the lines of:&lt;br /&gt;&lt;pre&gt;void thread_function(int *return_code)&lt;br /&gt;{&lt;br /&gt;   *return_code = NO_ERROR;&lt;br /&gt;&lt;br /&gt;   try {&lt;br /&gt;       if(something_wrong) {&lt;br /&gt;           *return_code = ERROR_MYERROR;&lt;br /&gt;           return;&lt;br /&gt;       }&lt;br /&gt;   } catch(...) {&lt;br /&gt;       *return_code = ERROR_GENERIC;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This has serious software design implications:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Not only do you have to be careful not to throw exceptions from a new thread, you have to be careful that &lt;span style="font-style: italic;"&gt;no function you might call there will throw an exception&lt;/span&gt;. That's almost impossible to do, unless you're planning to use only code you've written (which is a completely unrealistic expectation in a real-world application), or if you only call C functions. Even so, bare in mind that even C++'s operator new throws a bad_alloc exception when it runs out of memory,  so you can't really promise that nothing you call in your new thread will ever throw an exception.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You need to &lt;span style="font-style: italic;"&gt;think of new threads as processes in their own right&lt;/span&gt; (which on some UNIX systems is indeed exactly what they are underneath that POSIX threads API gloss). That means, whatever code you're using in your thread, &lt;span style="font-style: italic;"&gt;make sure you're always catching all the exceptions&lt;/span&gt; that could get thrown &lt;span style="font-style: italic;"&gt;before you exit the thread&lt;/span&gt;, and if you need to report problems, do it with a plain-old C-like return code. This is one of the places where the catch(...), or "catch-all" clause, doesn't seem so primitive.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-8685751730208486141?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/8685751730208486141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=8685751730208486141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/8685751730208486141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/8685751730208486141'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/c-rule-you-cant-catch-exception-from.html' title='C++ Rule: You Can&apos;t Catch an Exception from Another Thread'/><author><name>rc</name><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-9064003576220513352.post-404340467833913692</id><published>2008-05-05T12:04:00.000-07:00</published><updated>2008-05-05T12:34:33.888-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metacomments'/><title type='text'>Why "Jeeves with Classes"?</title><content type='html'>Because, C++, my favourite programming language (but not the best for everything), was initially called "C with Classes", by it's author, &lt;a href="http://www.research.att.com/%7Ebs/"&gt;Bjarne Stroustrup&lt;/a&gt;. &lt;a href="http://en.wikipedia.org/wiki/Jeeves"&gt;Jeeves,&lt;/a&gt; of course, is the name of P.G. Wodehouse's most well-known character, the always helpful guide for whatever characters had managed to get themselves in a fix.&lt;br /&gt;&lt;br /&gt;Though I do not intend to limit our discussion here to C++, C++ is a good conceptual tool to work with, because it is a multi-paradigm programming language. We'll sometimes be discussing high-level software design patterns, and sometimes implementation gotchas, and just for the fun of it, sometimes completely unrelated things just to take a break from the mundane. But mostly, I'm planning to share some of my humble experience working as a professional software designer and developer for the better part of the last decade of my life.&lt;br /&gt;&lt;br /&gt;In the hope that this will turn into an experience both entertaining and educational for both the reader and myself, I declare this blog open. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9064003576220513352-404340467833913692?l=jeeveswithclasses.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeeveswithclasses.blogspot.com/feeds/404340467833913692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9064003576220513352&amp;postID=404340467833913692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/404340467833913692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9064003576220513352/posts/default/404340467833913692'/><link rel='alternate' type='text/html' href='http://jeeveswithclasses.blogspot.com/2008/05/why-jeeves-with-classes.html' title='Why &quot;Jeeves with Classes&quot;?'/><author><name>rc</name><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></feed>
