<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Comments for page &quot;Why should I have written ZeroMQ in C, not C++ (part II)&quot;</title>
		<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii</link>
		<description>Posts in the discussion thread &quot;Why should I have written ZeroMQ in C, not C++ (part II)&quot;</description>
				<copyright></copyright>
		<lastBuildDate>Sat, 01 Aug 2015 21:47:19 +0000</lastBuildDate>
		
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-2279441</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-2279441</link>
				<description></description>
				<pubDate>Sun, 26 Apr 2015 15:44:04 +0000</pubDate>
				<wikidot:authorName>Ernie Cohen</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I think that Ambroz's point is that by introducing a separate list_node type, you would improve your program structture, without paying any performance penalty:</p> <p>- Lists can be treated as a separate abstract data type. As long as the client code (e.g., the code that works on my_entry above) respects this data abstraction, there is no encapsulation problem. (Programmers who cannot maintain this discipline should not be programming in C.)<br /> - You eliminate code duplication (currently, you have to write the pointer manipulation code for each kind of object that might be on a list).<br /> - You can change the type of list without having to change the client code (except to change the type of node).</p> <p>Of course the my_entry code has to know about where its representative list_nodes are, so it's still intrusive in that sense, but that's okay.</p> <p>This polymorphic linked structure trick is a standard C programming idiom (though known to distressingly few C programmers), and good programming practice.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-2058601</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-2058601</link>
				<description></description>
				<pubDate>Wed, 25 Jun 2014 21:14:51 +0000</pubDate>
				<wikidot:authorName>Rado</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>To cut reasoning short, if you managed in your C++ part of the code achieve O(N) where O(1) is expected, you got something badly wrong. Correct your design, and for free you will get rid of the nonsense &quot;not-really-C++&quot; code above.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-2009576</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-2009576</link>
				<description></description>
				<pubDate>Wed, 09 Apr 2014 19:42:49 +0000</pubDate>
				<wikidot:authorName>Vitali</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>It sounds like you're pretty much against C++ regardless of any actual corrections to misunderstandings you may have about it (C++11 fixes quite a few defects). I agree that it's a complicated language and it's easier to shoot yourself in the foot than with other languages (however this is even more true with C).</p> <p>First, I'm not sure what you mean by bad at resizing. What particularly about it is bad?</p> <p>Re vector vs list, cache misses are a drastically significantly more important performance impact than anything else these days &amp; you're guaranteed them when using a list unless you do lots of jumping through hoops to allocate everything in a contiguous array (but then why not vector?).</p> <p>I highly recommend you watch <a href="http://channel9.msdn.com/Events/Build/2014/2-661">http://channel9.msdn.com/Events/Build/2014/2-661</a> (the performance stuff starts roughly around the 20 minute mark) &amp; is language agnostic (true for C++/C/Java, etc).</p> <p>Additionally, in C++11, if you declare your move constructors noexcept (or use the default one or omit destructor, move/copy contructors &amp; move/copy assignment operators), then resizes of vectors can be much faster (if the move constructor is faster than the copy one) since the container doesn't need to copy your objects, it'll just move them.</p> <p>C++11 lets you also express your non-assignable types without resorting to pointers by declaring the type to be move only (thus Person can live on the stack or moved to live in the heap):</p> <div class="code"> <pre> <code>class Person { public: ~Person(); Person(const Person&amp; o) = delete; Person(Person&amp;&amp; o) noexcept : // initialize member variables with the resources from o { // modify o so that it no longer owns any resources // but leave it in a destructible state } Person&amp; operator=(const Person&amp;) = delete; Person&amp; operator=(Person&amp;&amp; o) noexcept { Person tmp(std::move(o)); swap(*this, tmp); return *this; } private: friend void swap(Person&amp;p1, Person&amp; p2) noexcept; };</code> </pre></div> <br /> Additionally, it's unlikely that Person would actually own anything. Instead you can omit all the constructors: <div class="code"> <pre> <code>class Person { public: Person(); // don't specify destructor or move/copy constructors/assignment operators // &amp; this type is implicitly move-only due to _data being move-only, it's exception-safe // &amp; everything is automatically annotated noexcept for you private: std::unique_ptr&lt;PersonData&gt; _data; };</code> </pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1988840</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1988840</link>
				<description></description>
				<pubDate>Tue, 11 Mar 2014 17:02:38 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes. But vectors are pretty bad a resizing. It's a trade-off.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1988817</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1988817</link>
				<description></description>
				<pubDate>Tue, 11 Mar 2014 16:37:20 +0000</pubDate>
				<wikidot:authorName>erapert</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Linked lists almost always suck compared to vectors because the way they lay out memory causes a lot of cache misses and because iterating through them is so expensive.<br /> <a href="http://www.youtube.com/watch?v=YQs6IC-vgmo">http://www.youtube.com/watch?v=YQs6IC-vgmo</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1935934</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1935934</link>
				<description></description>
				<pubDate>Tue, 14 Jan 2014 18:54:53 +0000</pubDate>
				<wikidot:authorName>Roy Pfingsten</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>This is a practical work-around, not a theoretical solution, but FWIW, you could allocate a &quot;spare&quot; memory pool you can borrow from when memory exhaustion becomes a problem.</p> <p>It will not protect against all conditions, especially not a memory leak in another running process, but it could keep things going long enough to print dire warnings to the console, stderr, etc, and optimistically, allow your app to survive long enough to realloc() to restore the size of the &quot;spare&quot; memory pool.</p> <p>What it will do is give you something useful to do to recover from malloc() when it returns a null - namely realloc() &quot;spare&quot; to something smaller to free up the memory you need. Hopefully.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1896365</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1896365</link>
				<description></description>
				<pubDate>Tue, 19 Nov 2013 14:31:18 +0000</pubDate>
				<wikidot:authorName>Cleroth</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Fixed in C++11.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1896363</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1896363</link>
				<description></description>
				<pubDate>Tue, 19 Nov 2013 14:30:13 +0000</pubDate>
				<wikidot:authorName>Cleroth</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Quite honestly, std::list should be avoided in most code, as other containers will usually outperform it nowadays in all aspects, and even when it doesn't (like when coding a networking library, or applications requiring heavy I/O), then you'd be better off using your own linked list.</p> <p>Conclusion&#8230; never use std::list. But to go as backwards as to use C&#8230; I think it's taking it a bit far.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1894318</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1894318</link>
				<description></description>
				<pubDate>Sat, 16 Nov 2013 14:43:59 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Nice example, thanks for introducing it!</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1889342</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1889342</link>
				<description></description>
				<pubDate>Sun, 10 Nov 2013 05:35:36 +0000</pubDate>
				<wikidot:authorName>SasQ</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Interesting article indeed!<br /> During my programming life I have been stumbling upon similar problems with encapsulation standing in a way of performance many times.<br /> Unfortunately, I see that the particular example used by Martin (that is, the list) have the discussion off-tracked into some list-detailed discussion which actually avoided the core of the problem which began all of that. So let me give you another example, from another field of programming, where I found a similar problem to this one:<br /> bit(dot)ly(slash)1kLqrZ<br /> This time, the problem is with efficiency of vector dot product. Making vectors to be instances of a class (that is, encapsulated objects) makes it harder for the compiler to reorder the code in a way that could be inlined or parallelized (don't confuse with paralyzed ;-) ). Observations show that dotting vectors can be done more efficient when each separate component can be worked out separately, because then the compiler can reuse memory for these components. But when those components are encapsulated in an object, this capsule firewalls the code of each mathematical operation, so there's no way to calculate all operations for one component and then do the same with the next component. The compiler needs to work out the particular operation for all the components before moving on to the next operation. This needs `n` times more memory (where `n` is the number of components), and makes inlining of these operator functions more difficult (if not impossible).</p> <p>The solution given in the aforementioned article is to use so called &quot;expression templates&quot; which wrap the parts of the expression and solve the order of operations in the compile time, reordering them in a way that the compiler can then optimize it further. This compiles to the code which could be hand-crafted by a C programmer, but it requires a real mess of templates to emulate in C++ what I'd call &quot;lazy-evaluated expressions&quot;. So it requires a lot of jumping through hoops to hack one's way around the encapsulation and to make the code efficient again, as it would be in C (but retain the type-safety of C++, which cannot be done in C, you need to admit). And I wonder, too, if this is really a flaw of OOP or just its implementation in C++.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1840198</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1840198</link>
				<description></description>
				<pubDate>Mon, 26 Aug 2013 13:40:03 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>How come?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1840147</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1840147</link>
				<description></description>
				<pubDate>Mon, 26 Aug 2013 11:50:50 +0000</pubDate>
				<wikidot:authorName>hualuogeng</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>The complexity of std::list&lt;&gt;::remove is not constant, but linear in container size (comparisons).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1798435</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1798435</link>
				<description></description>
				<pubDate>Mon, 17 Jun 2013 18:49:15 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>The assumption is that the object is not assignable (imagine object that contains a running thread). Thus, there's need to store it in the list by reference, rather than be copying it.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1798419</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1798419</link>
				<description></description>
				<pubDate>Mon, 17 Jun 2013 18:30:34 +0000</pubDate>
				<wikidot:authorName>AcidZombie24</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Actually you're wrong about the extra allocations with stl containers/iterators. Using vector&lt;person&gt; (not the lack of *) I had exactly 0 overhead. The class is exactly 8 bytes <a href="http://ideone.com/C4j0BG">http://ideone.com/C4j0BG</a></p> <p>Using list I get 24 bytes. I'm not sure where the extra few bytes comes from but that may be solved using a different implementation. Templates/oops doesn't cause extra allocations <a href="http://ideone.com/qGp2Am">http://ideone.com/qGp2Am</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1733620</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1733620</link>
				<description></description>
				<pubDate>Tue, 19 Mar 2013 04:38:12 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I recall the generic programming was all hip by the end of the last century already, when the compilers were barely able to cope with it. So I guess there must be some new buzzword paradigm today that makes even generic programming feel so last century.</p> <p>Anyway, I am all for computing as much as possible in compile-time, however, there always remain couple of pesky little things that must be computed in run-time ;)</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732991</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732991</link>
				<description></description>
				<pubDate>Mon, 18 Mar 2013 11:58:57 +0000</pubDate>
				<wikidot:authorName>Bronek Kozicki</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>BTW, must admit that for me using dynamic polymorphism (and, by extension, OOP), feels &quot;sooo last century&quot; ;) I feel more natural coding in C++ using generic style, with dynamic function despatch relegated to role similar to function object, i.e. useful but not essential.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732985</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732985</link>
				<description></description>
				<pubDate>Mon, 18 Mar 2013 11:45:15 +0000</pubDate>
				<wikidot:authorName>Bronek Kozicki</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I never had opportunity to use boost Meta State Machine (because I tend to avoid state machines), but I followed the initial stages of its design and it seemed quite nice and, on conceptual level, simple enough. Not sure what complexities it might have accrued over the years, just check it out.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732970</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732970</link>
				<description></description>
				<pubDate>Mon, 18 Mar 2013 11:14:38 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>STL is the most beautiful library I've ever seen and the fact that concepts haven't got into C++11 is a shame. Anyway, it's not relevant here.</p> <p>If by stressing the multi-paradigm character of C++ you mean that I should write plain old C and compile it with C++ compiler, sure, but then there's this pesky little dependence on libstc++ which gets pretty annoying, especially on embedded platforms.</p> <p>Please mind that I am not against OO paradigm itself. The idea that people tend to think in terms of objects rather than functions is a profound insight, maybe the deepest one made in the history of programming languages. The problem is that the abstract notion of &quot;object&quot; is in reality downgraded to a simple &quot;continuous chunk of memory&quot; concept. While that works OK in most cases, there are cases where the abstraction leaks. For example: intrusive containers. Here a single chunk of data is split between two objects (container &amp; the item). Another example: state machines. People tend to think about states as objects (they have well specified behaviours, each has a set of methods (events) etc. However, all the states in the state machine share the same data. Yuck!</p> <p>So, I guess, the question is rather whether OO paradigm can be extended to take account of these cases.</p> <p>Btw, given that you seem interested in various techniques to make things work in C++, have you ever come over some neat trick to implement state machines?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732957</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732957</link>
				<description></description>
				<pubDate>Mon, 18 Mar 2013 10:28:25 +0000</pubDate>
				<wikidot:authorName>Bronek Kozicki</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>&quot;not all the problems align nicely with object-oriented model&quot;</p> <p>Here is your problem - you are trying to fit round peg into square hole. Despite of what you might have learned, and practised, C++ is not a &quot;object oriented programming language&quot;; from the horse's mouth www.stroustrup.com (slash) oopsla.pdf . It is a multiparadigm programming language. It supports concepts such as decoupling, reusability and interfaces via many different means of which OOP is just one. E.g. standard template library depends on implicit interfaces without inheritance (you know what &quot;begin()&quot; and &quot;end()&quot; do, without having to rely on hypothetical IContainer class), reusability in procedural style works surprisingly well in connection with templates, defining implementation detail classes in a implementation files rather than in headers does decoupling pretty well, selection of code execution paths based on non-type template parameters often gives better results than inheritance etc.</p> <p>Never mind, you are an old dog now, it would be silly of me to try to teach you new tricks. Just say one thing: I used C++ some 20 years and almost gave up 10 years ago because OOP felt too limiting and clumsy (I've been programming in Lisp before). Then I read &quot;Exceptional C++&quot; series from Herb Sutter and this opened my eyes - there are more tools in C++ tool chest than in any other language, but somehow I've missed large proportion of those!</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732041</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732041</link>
				<description></description>
				<pubDate>Sat, 16 Mar 2013 14:57:35 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Well, I've used C++ past 15 years on day-to-day basis and I've gradually stopped using one feature, then another etc. At this point almost noting remains. And what remains is not worth of retaining dependency on C++ runtime library. (OK, I admit, templates are cool, despite of their awful syntax).</p> <p>My conclusion after passing the whole way is that C++ is for rapid development, not for system-level code.</p> <p>The fundamental problem, I believe, is that not all the problems align nicely with object-oriented model (e.g. state machines, rigorous error handling, low-level optimisation etc.) Of course, you can *not* use OO model in C++, but the it just looks silly. C, on the other hand, being so basic and low-level aligns well with any paradigm you can think of. And, of course, writing OO code in C is easy.</p> <p>Btw, some interesting research was done in PARC. &quot;Aspect oriented programming&quot; &#8212; an attempt to capture various aspects of a program (e.g. object model, failure model, state machines) using different languages and then compose the partial descriptions of the system into a single executable. It's tricky though. However smart the guys in PARC were I think the problem was just too hard in this case.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732026</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732026</link>
				<description></description>
				<pubDate>Sat, 16 Mar 2013 14:13:23 +0000</pubDate>
				<wikidot:authorName>Bronek</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>&#8230; as the code provided by maninalift (MqAloPgJ at codepad, above) demonstrates!</p> <p>Sorry, should have made if clear in my post earlier.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1732024</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1732024</link>
				<description></description>
				<pubDate>Sat, 16 Mar 2013 14:09:43 +0000</pubDate>
				<wikidot:authorName>Bronek</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>The discussion lives on :)</p> <p>Martin, your problem with C++ is not a C++ problem. It is a problem with how certain (majority?) programmers use it. It is also a problem with inefficiencies in C++ standard library (admittedly, part of the language standard-wise, but you can write perfectly valid C++ without it). Back to your example: no-one prevents you from picking and using the parts of C++ which go in hand with the goals of your project, and simply banning (by means of coding standard) parts which you do not like. In case of your list&lt;person&gt; example: you can make your own intrusive list rather than use std::list. Simple as that. This can be done either by means of list defining internal template structure which either inherits from person or keeps it in a non-static member variable (either way, person becomes a subobject of internal implementation detail, thus giving exactly same object layout as your C example); alternatively you may impose that person shall expose two pointers person* next and prev (C++ gives you means to enforce this), this way allowing you to implement list in the same way you would do it in C.</p> <p>One important thing that C users often forget about C++ is that you *do not have* to use all of its features. You get to use the features which make sense *for your project*, and if this subset excludes things like exceptions, dynamic polymorphism, standard library or whatever else, that's OK. You still get to benefit from things you left in (access control, perhaps? static polymorphism?). If this excludes almost all of C++ , then perhaps you just have to admit that you do not know C++ well enough to use if efficiently? In which case there is little point complaining about its inefficiencies &#8230;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1696986</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1696986</link>
				<description></description>
				<pubDate>Mon, 28 Jan 2013 13:33:31 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>OK. Give it a stab.</p> <p>However, I believe the problem is inherent: You can improve the code until it is cleanly implemented intrusive list. Then you have parts of the list object leaking into item object (next, prev). You need to ensure that these won't be used by anyone other than the list. So you'll probably go with something like the enclave pattern. At that point you should look on the code and ask: Are all these hacks used to get something that C++ promises out of the box (member access control) really worth it? Wouldn't it be cleaner to use raw C instead?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1696970</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1696970</link>
				<description></description>
				<pubDate>Mon, 28 Jan 2013 13:00:20 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>&#8230;ok this is interesting.</p> <p>I thought we were talking about a linked list and that the problem was simply going to be one of choosing which intrusive linked-list implementation best fitted the problem.</p> <p>This however is a much less well defined problem, but quite interesting.</p> <p>What is going on in the code now is clearly not ideal.</p> <p>That array class is crazy, just some thoughts so far, no need to respond:<br /> 1) why do we want random access to an array which does not<br /> guarantee order is preserved? certainly it doesn't seem like a priority<br /> that this is O(1)<br /> 2) pointers can be invalidated because deletion of objects does not remove them<br /> from the array - this leads to a need to always check the pointers.<br /> 3) pointers can be invalidated because we are allowed access to the pointers<br /> by reference<br /> 4) the array indexes can be invalidated because set_array_index is public.<br /> 5) The comments claim that insertion in O(1) but this is only average time.<br /> Worst case time is bad because push may require new memory allocation and<br /> copying of the array.</p> <p>An intrusive linked list could actually solve all of these problems, though iteration would obviously be slower and if there is some reason why you need O(1) random access via index then that would be a problem too. Intrusive linked lists do not require any allocations to add existing nodes to a list, for this reason they are good for &quot;real time&quot; applications.</p> <p>On the broader question of how to design the locking properly I am going to have to study the code more and review the literature in this area. I have a few ideas.</p> <p>I'm gonna stop myself babbling, I will probably go quiet for a while but I will try to come back to you with something useful.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1695833</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1695833</link>
				<description></description>
				<pubDate>Sat, 26 Jan 2013 20:31:46 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>black magic: It compiles into a single subtraction operation, so it's very quick. Also, it's done on regular basis in linux kernel so my guess is there is no serious performance problem like messing with optimiser. If there was, it would have been fixed long time ago.</p> <p>&quot;that sounds like a job for typestate. Implementing some approximation of this with C++ metaprogramming sounds like a very interesting project (and as I think of it, some new C++11 features, in particular type erasure and variadic templates might help a lot)&quot;</p> <p>Go for it. It would be interesting to see what C++11 has to offer in terms of decoupling memory layout from accessibility settings.</p> <p>&quot;I'm sorry I just don't have the context to understand the problems with this sort of example. If you can point me to where I can find the code, which classes in particular are problematic (what corresponds to A B C and D) then I will try to deal with the complexity or admit defeat.&quot;</p> <p>0MQ goes to great lengths to avoid this kind of problem. See the convoluted algorithm for managing list of pipes in lb_t and fq_t classes. The list stores pipe index (position in the list) inside of the pipe, however, pipe is not necessarily living in the same thread as the list. What you get is members that are living in different threads packed without any safeguards into a single class. There are lock-less algorithms involved etc. so it's really top complex system to demostrate theoretical issues on.</p> <p>The ABCD snippet in the previous post is much cleaner example. The only goal is to ensure that individual variables are accessed only by their owners, i's by A, j's by B. Attempt to access say C::i from B or C should yield a compile-time error.</p> <p>The only solution I can think of is along the lines of enclave pattern, I've described in my blog. However, that's hardly an idiomatic C++ and leaves me asking whether using plain old C is not a better solution.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1695821</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1695821</link>
				<description></description>
				<pubDate>Sat, 26 Jan 2013 20:11:54 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>black magic: that's interesting - does that allow you to access a member of a struct via a pointer to another member as efficiently as if you had a pointer to the struct itself or is there another step involved? I would also be interested to find out whether in any circumstances this sort of trick prevents optimizations by obfuscating what we are doing to the compiler&#8230; very interesting.</p> <p>&quot;If possible, make compile complain when synchronisation is done incorrectly&quot;<br /> that sounds like a job for typestate. Implementing some approximation of this with C++ metaprogramming sounds like a very interesting project (and as I think of it, some new C++11 features, in particular type erasure and variadic templates might help a lot)</p> <p>&quot;0MQ code is to convoluted to be discussed here, but try adding proper encapsulation to this&quot;<br /> I'm sorry I just don't have the context to understand the problems with this sort of example. If you can point me to where I can find the code, which classes in particular are problematic (what corresponds to A B C and D) then I will try to deal with the complexity or admit defeat.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1695488</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1695488</link>
				<description></description>
				<pubDate>Sat, 26 Jan 2013 06:32:00 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>0MQ code is to convoluted to be discussed here, but try adding proper encapsulation to this:</p> <div class="code"> <pre> <code>class A { mutex m; /* uses and synchronises C::i and D::i */ }; class B { mutex m; /* uses and synchronises C::j and D::j */ }; class C /* doesn't use C::i or C::j */ { int i; int j; }; class D /* doesn't use D::i or D::j */ { int i; int j; };</code> </pre></div> <p>As for the black magic, casting from member to the container is a standard way of doing things in C. Check e.g. Linux kernel sources.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1695164</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1695164</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 22:02:37 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>&quot;My problem is as follows:&#8230;.&quot;<br /> Can I see the actual code? I searched zeroMQ for use of std:list and came up empty handed.</p> <p>&quot;I've actually written a blog post about this&quot;<br /> Something like that but the next and previous pointers in the helper class need to point to person objects because you can't get to the person class from the helper class and all you are left with is a linked list of helpers (I guess strictly you could probably do some black magic where you find the offset of the helper data I'm assuming that's not what you wanted to do).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694942</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694942</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 19:13:11 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>&quot;can quite easily make their methods private but share them by friendship&quot; &#8212; I've actually written a blog post about this: <a href="http://www.250bpm.com/blog:9">http://www.250bpm.com/blog:9</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694938</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694938</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 19:10:37 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Ok, let's go for it! :)</p> <p>My problem is as follows:</p> <p>I have many classes in the project, each has many members. I have also few mutexes. Each mutex synchronises some (but not all) members in some classes. Say mutex 1 synchronises A::a, A::b, B::i and C::x, while mutex 2 synchronises A::c and C::y etc.</p> <p>Now, the challenge is:</p> <ol> <li>How to keep track of which mutex synchronises which variables</li> <li>If possible, make compile complain when synchronisation is done incorrectly</li> </ol> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694932</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694932</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 19:02:54 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>&quot;but then some of the properties of the box (prev,next) leak into chocolate object&quot;<br /> Intrusive containers' helper objects (the equivalent to my list_node) can quite easily make their methods private but share them by friendship with the list and iterator classes so that the appear from the outside as a normal container class. say &quot;intrusive but not obtrusive&quot;</p> <p>&quot;I would say there's no way out, unless the language doesn't enforce tight coupling between objects and memory allocations.&quot;<br /> Not necessarily but it is the easiest way of telling the compiler how the data should be laid-out. If you break the coupling between object and memory structure you will end up having to look up every property like Ruby and its dynamic bretheran, and that is a _lot_ slower.</p> <p>Could you point me to the actual code where this is a problem. Talking in the abstract and with toy examples can end up going 'round in circles.</p> <p>I wager I can find a C++ solution that will deliver better encapsulation, making your code safer, more expressive and easier to maintain, without compromising runtime performance when compared to the bare C solution you describe. And that even in this case to which you feel C++ is particularly unsuited.</p> <p>I say this with all humility, knowing I am not an equal to you as a software engineer.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694560</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694560</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 11:01:51 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>:)</p> <p>Ok, I guess you are into a more theoretical discussion. Here's my take then:</p> <p>What OOP delivers is a way to decompose the universe into well-delimited objects. The appeal is that human brain is wired to deal with well-delimited objects and thus OOP allows common sense to kick-in (rather than pseudo-scientific reasoning required by non-object-oriented code).</p> <p>In other words, if there's a box of chocolates, common sense assumes that these are two well-delimited objects and there's nothing chocolate-like about the box and nothing box-like about the chocolates.</p> <p>So far so good. There's nothing wrong about OOP paradigm.</p> <p>Enter C++. C++ have evolved from C and re-used C &quot;struct&quot; construct to define classes. What that means is that &quot;well-delimited object&quot; maps to &quot;continuous chunk of memory&quot; in C++.</p> <p>This tight coupling between &quot;object&quot; and &quot;memory allocation&quot; works well in most cases, however, in few special cases it goes astray. When thinking about lists, the only way to separate box properties from chocolate properties is to allocate 2 memory chunks instead of a single one per chocolate in the box. That's basically what STL does.</p> <p>Intrusive containers merge the two chunks into a single one, but then some of the properties of the box (prev,next) leak into chocolate object. Which, of course, violates the basic promise of the OOP paradigm (well-delimited objects).</p> <p>I would say there's no way out, unless the language doesn't enforce tight coupling between objects and memory allocations.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694558</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694558</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 10:41:07 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>quite!</p> <p>This is exactly what the library-implemented templated intrusive-list solves (preferably something better thought out than the code I posted, boost probably has one).</p> <p>The programmer has accepted that his object &quot;is a&quot; node in the list, in that sense that is part of what the object it but he still wants implement and use this in a safe, neat, reusable way.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694507</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694507</link>
				<description></description>
				<pubDate>Fri, 25 Jan 2013 08:39:52 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I was wary about using the word &quot;encapsulation&quot; to describe the OO-ness that the code preserves.</p> <p>The point is, you can write an intrusive list that is not intrusive in your client code. Yes you have to inherit from the node class but (my implementation is not full, but Google it someone has probably done it), but the important point is if you were to need to change the design and re-factor your code it would be relatively easy, depending what you are doing of course you will probably only have to touch the class definitions not the client code. It does not &quot;degenerate to C style&quot;</p> <p>Talking about what &quot;a C++ programmer&quot; would do is really a straw man argument. The point is C++ generics provide the tools to represent any abstraction you might think of and do so without any run-time overhead. Yes the implementation of the patterns can look pretty scary (in large part to the verbose template syntax) but usage usually has acceptable to good syntax.</p> <p>I have been reading a lot of language specifications and papers on different type systems and programming paradigms recently and the biggest surprise that I have had from the whole project is that it turns out most of the ideas can be implemented in a usable way as a C++ library. Think very carefully before you say something can't be done.</p> <p>Finally if you have a case where your code is easier to read and maintain and more efficient in C style then do it, it certainly doesn't mean that your whole project has to &quot;degenerate&quot;.</p> <p>Why do I care enough to write this?<br /> answer 1: C++ provides the tools to let you deal with abstractions at compile-time, C doesn't. In C you must therefore either do without the abstraction or use run-time abstractions leading to just the sort of indirection this article seeks to avoid.<br /> answer 2: I'm a geek<br /> answer 3: someone is wrong on the internet ;¬)</p> <p>PS I have very much enjoyed using ZeroMQ</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694074</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694074</link>
				<description></description>
				<pubDate>Thu, 24 Jan 2013 22:50:07 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>From the article: &quot;The real reason why any C++ programmer won't design the list in the C way is that the design breaks the encapsulation principle: The implementer of the &quot;person&quot; class has to know that its instances will be eventually stored in &quot;people&quot; list. Moreover, if a 3rd party chooses to store it in a different list, the implementation of the person would have to be change. This is an anti-pattern that OO programmers learned to avoid.&quot;</p> <p>See, the object needs to know that it will be part of the list:</p> <p>class important_object: public list_node&lt;important_object&gt;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694038</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694038</link>
				<description></description>
				<pubDate>Thu, 24 Jan 2013 22:15:09 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>sure you can keep encapsulation, write idiomatic C++ and not be left with the overhead of any superfluous run-time overhead:</p> <p>Find code on codepad (dot) org (slash) MqAloPgJ</p> <p>and whats more you get list elements that remove themselves when they are deleted resulting in cleaner, safer code.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1694035</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1694035</link>
				<description></description>
				<pubDate>Thu, 24 Jan 2013 22:13:32 +0000</pubDate>
				<wikidot:authorName>maninalift</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>sure you can keep encapsulation, write idiomatic C++ and not be left with the overhead of any superfluous run-time overhead:</p> <p>Find code on codepad (dot) org (slash) MqAloPgJ</p> <p>and whats more you get list elements that remove themselves when they are deleted resulting in cleaner, safer code.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1679450</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1679450</link>
				<description></description>
				<pubDate>Sun, 06 Jan 2013 17:23:37 +0000</pubDate>
				<wikidot:authorName>Karim</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I know that is too late :). But i am inheriting from Person not making Person as a subclass of something. so even it is not final class in another library. i can use that.</p> <p>It is like a proxy for the person class. that adds extra functionality to it.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1659951</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1659951</link>
				<description></description>
				<pubDate>Wed, 19 Dec 2012 18:14:30 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Say there's a running thread inside of the object. What then?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1659908</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1659908</link>
				<description></description>
				<pubDate>Wed, 19 Dec 2012 17:55:05 +0000</pubDate>
				<wikidot:authorName>Nevin &quot;:-)&quot; Liber</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>If it is non-copyable, just use emplace to put it in the list.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1622450</guid>
				<title>Re: Helpers do not exist</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1622450</link>
				<description></description>
				<pubDate>Tue, 20 Nov 2012 23:02:15 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>We are speaking about non-copyable objects here. What you get then is list&lt;myobject*&gt; and suddenly there's an extra chunk allocated.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1622375</guid>
				<title>Helpers do not exist</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1622375</link>
				<description></description>
				<pubDate>Tue, 20 Nov 2012 21:22:03 +0000</pubDate>
				<wikidot:authorName>ilejn</wikidot:authorName>				<wikidot:authorUserId>1209177</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello, Martin.</p> <p>Do you really believe that C++ requires extra chunk of memory in case of list?</p> <p>Have a look into STL sources and see something like<br /> ==<br /> <em>/ @if maint Common part of a node in the %list. @endif<br /> struct _List_node_base<br /> {<br /> _List_node_base* _M_next; /</em>&lt; Self-explanatory<br /> _List_node_base* _M_prev; ///&lt; Self-explanatory</p> <p>static void<br /> swap(_List_node_base&amp; __x, _List_node_base&amp; __y);</p> <p>void<br /> transfer(_List_node_base * const __first,<br /> _List_node_base * const __last);</p> <p>void<br /> reverse();</p> <p>void<br /> hook(_List_node_base * const __position);</p> <p>void<br /> unhook();<br /> };</p> <p><em>/ @if maint An actual node in the %list. @endif<br /> template&lt;typename _Tp&gt;<br /> struct _List_node : public _List_node_base<br /> {<br /> _Tp _M_data; /</em>&lt; User's data.<br /> };<br /> ==</p> <p>Helpers do not exist!</p> <p>It is the same object, it is one memory allocation, it is inheritance and it is C++ magic.</p> <p>Enjoy C++, it is really cool.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1597308</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1597308</link>
				<description></description>
				<pubDate>Thu, 25 Oct 2012 05:58:03 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>There's nothing else they can do. Modern OSes allow for memory overcommitment anyway, which means that allocation may succeed even if there isn't sufficient memory available.</p> <p>Even if that wasn't the case, what would you do if out-of-memory condition happened? Any attempt to recover may run out of memory itself. For example, years ago I've seen closing a file fail in low-memory conditions.</p> <p>Additionally, when you are running out of memory, OOM killer is probably already in progress and it may very well choose your application to be killed.</p> <p>In short, memory allocation errors are the primary candidates for &quot;fail fast&quot; strategy.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1597290</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1597290</link>
				<description></description>
				<pubDate>Thu, 25 Oct 2012 05:14:48 +0000</pubDate>
				<wikidot:authorName>Alex</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>GLib basically just craps itself when it runs of memory, making it laughable from the perspective of resilient code. Their attitude is:</p> <p>&quot;If any call to allocate memory fails, the application is terminated. This also means that there is no need to check if the call succeeded.&quot;</p> <p>&quot;no need&quot; - OMG. So, every single program using GLib can fail at any time, either through its own stupidity or any *other* program's attempt to grab too much RAM. The irony is that the other program may not be using GLib, and could easily survive and go on to use the memory freed up by the GLib program imploding. Which offers an easy to to get more RAM - grab all that's left and wait for a bit voila! More memory.</p> <p>GLib's memory exhaustion handling is a joke.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1585661</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1585661</link>
				<description></description>
				<pubDate>Thu, 11 Oct 2012 08:07:17 +0000</pubDate>
				<wikidot:authorName>Dimitris</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Can we all agree that code comprehensibility, provided by OO analysis and programming, is the most important thing until you start to optimize, at which point the OO concepts go down the drain? Your list example demonstrates this perfectly. It also does not occur in 95% (wild guess) of the production code out there.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1577158</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1577158</link>
				<description></description>
				<pubDate>Sun, 30 Sep 2012 19:36:35 +0000</pubDate>
				<wikidot:authorName>Simon Toth</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>No, intrusive list doesn't violate the OO paradigm (glancing over the fact, that C++ isn't an OOPL).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1568244</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1568244</link>
				<description></description>
				<pubDate>Wed, 19 Sep 2012 10:38:56 +0000</pubDate>
				<wikidot:authorName>Jaroslav Tulach</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Interesting read. I gave the paper to our performance team as a &quot;must-read&quot;.</p> <p>Btw. somebody nicked named &quot;jtulach&quot; (and in fact not me), provided effective and encapsulated C++ list on my http wiki(dot)apidesign(dot)org/wiki/Talk:Trait#jtulach_said_&#8230;_3<br /> I guess it shows C++ is not as bad as was originally thought.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1565131</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1565131</link>
				<description></description>
				<pubDate>Sat, 15 Sep 2012 08:01:52 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>The argument is more generic. Imagine that the 'person' object is implemented in a 3rd party closed-source library. There's no way to include it into an intrusive container.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1565128</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1565128</link>
				<description></description>
				<pubDate>Sat, 15 Sep 2012 07:57:13 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes, I would even rephrase it in a stronger way: OO provides benefits in terms of modularity and maintainability of the code. Unfortunately, in C++ these benefits cannot be realised when implementing intrusive containers. That's a failure of C++, not the OO paradigm as such.</p> <p>As for other OO languages, the problem is probably not even applicable as most of them don't let you mess with actual memory layout of your objects.</p> <p>Finally, in the subsequent blog (250bpm.com/blog:9) I've proposed the &quot;enclave&quot; programming pattern which to some extent mitigates the intrucive container vs. encapsulation problem.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1564839</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1564839</link>
				<description></description>
				<pubDate>Fri, 14 Sep 2012 22:41:11 +0000</pubDate>
				<wikidot:authorName>Walker</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I may not be understanding your concern, but if you use multiple inheritance and have the person class inherit from a virtual class that defines the methods needed for generic containment (this would be an interface in Java or C#) then your containers all would contain objects of that virtual class. No need to change the implementation of person class for the different containers.</p> <p>As a side note, it is generally accepted that multiple inheritance can be dangerous if more than one parent is not virtual.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1564810</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1564810</link>
				<description></description>
				<pubDate>Fri, 14 Sep 2012 22:04:07 +0000</pubDate>
				<wikidot:authorName>Walker</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I think this posting does a lot to clarify the point of your article. The only thing that still bothers me is the indication that instrusive containers are superior to STL containers and that the OO paradigm is therefore inferior. (I realize these are not your words and probably not even your intent&#8212;but, as posted, this is how it sounds.)</p> <p>Perhaps a more accurate wording would be that there are situations in which the OO paradigm imposes constraints that has a negative effect on code execution speed and/or memory allocation size. I offer as evidence the necessity to stipulate a very specific case in order to prove your argument.</p> <p>To balance this out, I think it is fair to say that there are situations in which the OO paradigm provide significantly more benefits than modular/structured programming alone. In particular on projects with N (more the two or three) programmers, a well designed OO program can get you a lot closer to the hypothetical 1/N development time. (I'll state the obvious&#8212;badly designed programs make the choice of language and development paradigm a minor issue.)</p> <p>This has been a very instructive experience&#8212;both the article and the resulting posts. I commend both Martin and the majority of the other posters for their informed focus on the issues and not on personalities. This is what good discussions should all be like.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1557983</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1557983</link>
				<description></description>
				<pubDate>Thu, 06 Sep 2012 20:21:45 +0000</pubDate>
				<wikidot:authorName>Griwes</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>C++ isn't a superset of C since very, very, very long time.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556700</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556700</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 14:14:10 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>True, &quot;private in&quot; would have to attach those fields to an unrelated struct, which is impossible without knowing the code of the entire program, to figure out what &quot;Person&quot; actually is. It would still break encapsulation, only on a lower layer.</p> <p>&quot;Imagine you want to store the same person in yet another container. How would you do that without breaking encapsulation?&quot;</p> <p>Well there are two ways to do that. If the other container is inherently related to my_person and will be handled in the same module, add extra fields to my_person:</p> <p>struct my_person {<br /> Person person;<br /> struct my_person *next;<br /> RbTreeNodeData tree_node;<br /> };</p> <p>On the other hand, if it's the *user of my_person* who needs to keep my_person's in another container, use the same technique as before, but on one layer above:</p> <p>struct my_barking_person {<br /> struct my_person person;<br /> RbTreeNodeData tree_node;<br /> };</p> <p>I've written a lot of code like this. It's very manageable, and if you have a large &quot;composition hierarchy&quot;, you save a lot of memory allocations (and memory).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556698</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556698</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 14:13:09 +0000</pubDate>
				<wikidot:authorName>Ivan</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>to clarify:<br /> &quot;Still idk what the hell list has to do with O(1) removal. :)&quot;<br /> By this I mean if caller only provides a value, not an iterator or ptr. If he does it is O(1) removal.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556693</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556693</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 14:07:34 +0000</pubDate>
				<wikidot:authorName>Ivan</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>&quot;<br /> 1. Implement a container with O(1) insertion and removal of any element. Assume that the element cannot be copied and thus should be referenced by a pointer:<br /> &quot;<br /> no can do. hash_map has O(1), but O(n) worst case. I guesstimate you meant if you provide the position(aka remove element at postion 1701 ).<br /> Still idk what the hell list has to do with O(1) removal. :)</p> <p>&quot;<br /> 2. No extra allocations should be made during the insert operation.<br /> &quot;<br /> preallocate, or when in STL do as the std::vector does(I guess you know about how vector capacity changes when there is no space for push_back()<br /> )<br /> &quot;<br /> 3. Make sure that encapsulation is not broken (i.e. adding the element to a new container doesn't require modifying the implementation of the element in question).<br /> &quot;<br /> Since element cant be copied you mean adding a pointer to an element to a new container ?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556658</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556658</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 13:13:19 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>One thing that puzzles me is that although there was total of like 500 comments to this article on different sites, but as far as I am aware nobody pointed out the most obvious problem, that implementing the &quot;private in&quot; thing would break the whole concept of compilation units, objects files etc.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556652</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556652</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 12:57:56 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <blockquote> <p>Old saying goes you shouldn't try to fix social problems with technical solutions :)</p> </blockquote> <p>That would imply private/protected/public keywords should be removed from C++ as they solve a social problem rather than a technical one.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556650</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556650</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 12:56:26 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <blockquote> <p>Basically, on insert, your container will eventually require some memory. If you do not wish this memory to be outside of the entries, it has to be preallocated within the entries. So either it's inefficient or it break encapsulation. There's no way out.</p> </blockquote> <p>Bingo!</p> <blockquote> <p>The Person code in the library does not need to know anything about my_person, so the encapsulation is not broken in this perspective.</p> </blockquote> <p>Imagine you want to store the same person in yet another container. How would you do that without breaking encapsulation?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556606</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556606</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 11:02:03 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Have you considered trying with no memory allocations at all? E.g. user would write:</p> <p>Person p;<br /> p.init();<br /> &#8230;<br /> p.deinit(); // assuming you don't want constructors/destructors :)</p> <p>This approach allows a *user* to efficiently keep persons in his own data structures:</p> <p>struct my_person {<br /> Person p;<br /> struct my_person *next;<br /> };</p> <p>The Person code in the library does not need to know anything about my_person, so the encapsulation is not broken in this perspective. The downside is it's prone to ABI breaks, but I'm not sure how relevant this is in your case.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-556302#post-1556594</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-556302/why-should-i-have-written-zeromq-in-c-not-c-part-ii#post-1556594</link>
				<description></description>
				<pubDate>Wed, 05 Sep 2012 10:34:18 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>In your proposed &quot;private in&quot; syntax, the list pointers are still within the person structure. The person still needs to be aware that it can be contained within the list. Adding it to another list still requires modifying the definition of person.<br /> The way I see it &quot;private in&quot; just enforces that only the implementation of the list can access those members. Someone accessing these fields when he shouldn't is really a social problem, not a technical one. Old saying goes you shouldn't try to fix social problems with technical solutions :)</p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>