<?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/blog:8/comments/show</link>
		<description></description>
				<copyright></copyright>
		<lastBuildDate>Sat, 01 Aug 2015 21:42:37 +0000</lastBuildDate>
		
					<item>
				<guid>http://250bpm.com/blog:8/comments/show#post-2279441</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-2058601</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-2009576</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1988840</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1988817</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1935934</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1896365</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1896363</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1894318</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1889342</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1840198</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1840147</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1798435</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1798419</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1733620</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1732991</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1732985</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1732970</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1732957</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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/blog:8/comments/show#post-1732041</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:8/comments/show#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>
				</channel>
</rss>