<?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 I)&quot;</title>
		<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i</link>
		<description>Posts in the discussion thread &quot;Why should I have written ZeroMQ in C, not C++ (part I)&quot;</description>
				<copyright></copyright>
		<lastBuildDate>Sat, 01 Aug 2015 21:47:25 +0000</lastBuildDate>
		
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2318778</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2318778</link>
				<description></description>
				<pubDate>Wed, 17 Jun 2015 06:16:08 +0000</pubDate>
				<wikidot:authorName>yourfriendlybutcher</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I just read the article and I think the author doesn't have much understanding of C++. Let's analyse it:</p> <blockquote> <p>However, what's great for avoiding straightforward failures becomes a nightmare when your goal is to guarantee that no undefined behaviour happens. The decoupling between raising of the exception and handling it, that makes avoiding failures so easy in C++, makes it virtually impossible to guarantee that the program never runs info undefined behaviour.</p> </blockquote> <p>I do not see from where that conclusion originates. Functions that are being called (and potentially fail with an error) should be decoupled from the caller. It doesn't matter if the error is propagated as an exception or a simple code. Error codes can be silently ignored, while exceptions can't, which means you are more likely to introduce bugs while using error codes. If you ignore an error condition and go on, your process might go into undefined behaviour territory. An exception will propagate to the nearest handler, cleaning every object along the way.</p> <blockquote> <p>int rc = fx ();<br /> if (rc != 0)<br /> handle_error ();</p> </blockquote> <blockquote> <p>int rc = fx ();<br /> if (rc != 0)<br /> throw std::exception ();</p> </blockquote> <p>These are not equivalent - far from it.</p> <blockquote> <p>The problem with that is that you have no idea of who and where is going to handle the exception.</p> </blockquote> <p>As it should be. Why should you care who handles the error? In your example, the function fx() obviously doesn't care - just informs that an error happened. You are advocating coupling callees with callers.</p> <blockquote> <p>(code examples)<br /> It's far more readable and — as a bonus — compiler is likely to produce more efficient code.</p> </blockquote> <p>First - it's not equivalent, since you also need to jump out after the error in C. The most common way I see with C programmers is using goto for that task (because you usually need to release resources and there is no RAII in C), which isn't readable at all and can introduce bugs. Can you recall scoping rules with goto out of your head? I don't think so.<br /> Second - if you forget about jumping out, your code will just go on thinking no error was generated.<br /> Third - you have no evidence of the compiler producing that much better code for the programmer to care. When it comes to trading safety for efficiency, you should go with the safety the exceptions provide you with.<br /> Fourth - I find exceptions far more readable - &quot;if X happened, generate error Y&quot;. What's not readable about that?</p> <blockquote> <p>However, it doesn't end there. Consider the case when the exception is not handled in the function that raises it. In such case the handling of the error can happen anywhere, depending on where the function is called from.</p> </blockquote> <p>That is exactly the point. Callee should not care who handles its errors. When a C function returns an error code, it doesn't care who handles it. The same logic applies to exceptions. Once again you are trying to tie callees with callers.</p> <blockquote> <p>As you fix individual bugs you'll find out that you are replicating almost the same error handling code in many places. Adding a new function call to the code introduces that possibility that different types of exceptions will bubble up to the calling function where there are not yet properly handled. Which means new bugs.</p> </blockquote> <p>If you don't handle an exception, the default handler will (terminating the process with an error message). If you don't handle an error code in C - nothing will inform you of that. Your process will go on in an erroneous state thinking everything is ok. Good luck debugging such errors.</p> <blockquote> <p>If you don't give up on the &quot;no undefined behaviour&quot; principle, you'll have to introduce new exception types all the time to distinguish between different failure modes. However, adding a new exception type means that it can bubble up to different places. Pieces of code have to be added to all those places, otherwise you end up with undefined behaviour.</p> </blockquote> <p>First - you won't end up with undefined behaviour, since the exception propagation is well defined by the Standard. You'll end up with the default handler which will show you the error message.<br /> Second - similar logic applies to error code. If you create a new error code, you need to handle it. If you don't, your process will silently go into some undefined state.</p> <blockquote> <p>Well, the problem is that exception specifications are just a tool to handle the problem of exponential growth of the exception handling code in a more systematic manner, but it doesn't solve the problem itself. It can even be said it makes it worse as now you have to write code for the new exception types, new exception handling code *and* new exception specifications.</p> </blockquote> <p>That really doesn't make sense. What is that problem that exceptions don't solve and error codes do? Please define it. Also - what exception specifications? If you're talking about throw(&#8230;) in declarations, those were always a bad idea and were discouraged. Now, they're deprecated and should never be used.</p> <blockquote> <p>Consider what happens when initialisation of an object can fail. Constructors have no return values, so failure can be reported only by throwing an exception. However, I've decided not to use exceptions.</p> </blockquote> <p>And that is your problem there. You decided to go against the language features and you ended up with some absurd semi-constructed states, which you need to handle manually. If you followed the language, that is:</p> <ul> <li>An object is considered constructed (initialized) when its constructor returns with no exception.</li> <li>With RAII, all your resources should be released in the destructor, making resource handling automatic.</li> </ul> <p>you'd find that your code is both safer and simpler. Object could be either constructed or not. Error would be signalled on failed constructions. Resources would be automatically freed.<br /> Instead you made a little hell for yourself, where you need to take that semi-constructed state into account, potentially introducing bugs.</p> <blockquote> <p>Now you say: But that's just a consequence of your artificial restriction of not using exceptions! If exception is thrown in a constructor, C++ runtime cleans the object as appropriate and there is no 'semi-initalised' state whatsoever!</p> <p>Fair enough. However, it's beside the point.</p> </blockquote> <p>No, it's not beside the point. The whole point is about you fighting the language, instead of using its features to make safe code.</p> <blockquote> <p>And that is not a reasonable option for an infrastructure component with the need to be very robust in the face of failures.</p> </blockquote> <p>As a person who is making such &quot;infrastructure components&quot;, as you called them, I claim you are totally wrong on that front. Proper usage of exceptions and proper usage of language features make your code resistant to failures and very safe. Fighting against it is what lead you to this mess, and you try to blame the language for it.</p> <blockquote> <p>Moreover, even if initialisation wasn't a problem, termination definitely is. You can't really throw exceptions in the destructor. Not because of some self-imposed artificial restrictions but because if the destructor is invoked in the process or unwinding the stack and it happens to throw an exception, it crashes the entire process.</p> </blockquote> <p>Right - you should not throw form the destructor (they are noexcept now, in fact). Try to think about more closely - you are releasing resources and you encounter an error. If this is not critical and the process can continue, you can safely not throw. If it it's critical, you should terminate because, well, it's critical.</p> <blockquote> <p>Thus, if termination can fail, you need two separate functions to handle it</p> </blockquote> <p>No, just follow RAII. You'll get a safe and reliable way of automatically releasing resources in a single function - the destructor.</p> <blockquote> <p>However, once you introduce separate init functions, the number of states starts to grow.</p> </blockquote> <p>So you see why your idea of semi-states is bad. Why do you advocate it then?</p> <blockquote> <p>With objects like these it's almost impossible to guarantee predictable behaviour.</p> </blockquote> <p>You created a problem which doesn’t really exist, if you follow the simple rules. You then created a really bad workaround to that problem. And, in the end, you list the reasons why your solution is bad. That's absurd.</p> <blockquote> <p>To summarise the above, I believe that requirement for fully-defined behaviour breaks the object-oriented programming model. The reasoning is not specific to C++. It applies to any object-oriented language with constructors and destructors.</p> </blockquote> <p>Pretty much every piece of code, which is made with proper fashion, proves you wrong. Don't fight the language, but learn to use it to your advantage. You'll find all your problems are really artificial.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2301239</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2301239</link>
				<description></description>
				<pubDate>Fri, 22 May 2015 21:24:51 +0000</pubDate>
				<wikidot:authorName>mark</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>(This was supposed to be a top-level comment. Usability problem uncovered.)</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2301236</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2301236</link>
				<description></description>
				<pubDate>Fri, 22 May 2015 21:21:04 +0000</pubDate>
				<wikidot:authorName>mark</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Can you make an example for a destructor that can fail? For example if an attempt to close a file fails (which it should never do) then the appropriate action would be to log the error and simply do nothing else.</p> <p>The first point of yours was that certain exception patterns are awkward. I agree - so simply don't do it this way. Don't use exceptions for control flow. If, when throwing, you need to know who catches the error then it is a misuse of exception handling and too tight of a coupling. Exceptions are to be treated as special return values that automatically bubble up as a default behavior.</p> <p>If an operation is expected to fail sometimes, and meaningful actions can be taken as a result, then error codes as return values are totally reasonable. They mix with exceptions well.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2300783</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2300783</link>
				<description></description>
				<pubDate>Fri, 22 May 2015 08:12:51 +0000</pubDate>
				<wikidot:authorName>Luca Bruno</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>For data structures you can still mix C with C++, that's what I do. For sets, hashtables, ecc. I use a simple wrapper c++ class that I use from C.<br /> Also there are glib data structures, the hashtable is quite efficient. Glib is very portable.<br /> Just depend on libraries man and don't be afraid. That's what libs are for, for being dependencies.</p> <p>For destructors being invoked at the end of the block, you can do that too with C: <a href="http://echorand.me/site/notes/articles/c_cleanup/cleanup_attribute_c.html">http://echorand.me/site/notes/articles/c_cleanup/cleanup_attribute_c.html</a></p> <p>For virtual methods, I agree it's quite painful, but for a schema that's working in years you can look at gobject and how they do it. For a single class there are two data structures, the instance struct and the class struct. The class struct is where you put the vtable.<br /> That means you have a single vtable for one class instead of having one vtable per-instance.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2300075</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2300075</link>
				<description></description>
				<pubDate>Thu, 21 May 2015 12:59:18 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I did: nanomsg.org</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2300071</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2300071</link>
				<description></description>
				<pubDate>Thu, 21 May 2015 12:46:47 +0000</pubDate>
				<wikidot:authorName>time_t</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>If you think c++ is bad choice for ZeroMQ, why don't you rewrite it using c?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2298181</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2298181</link>
				<description></description>
				<pubDate>Tue, 19 May 2015 11:14:36 +0000</pubDate>
				<wikidot:authorName>Greg</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>here</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2298179</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2298179</link>
				<description></description>
				<pubDate>Tue, 19 May 2015 11:06:34 +0000</pubDate>
				<wikidot:authorName>Greg</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I don't see what the big deal is hear.</p> <p>While exception do allow the de-coupling of handling from cause, they don't heve to be used that way. You can stop exceptions propagating out of any block and handle, assert or convert to c-style at whatever level you want.</p> <p>In an earlier example you talked about calling a third-party function that could generate any (to you) unknown exception, so just wrap it in a try&#8230;catch(&#8230;) and convert to a return FAIL or asssert, whechever you prefer. How is not using exceptions going to help in this situation?</p> <p>Almost all of C can be mis-used just as easily as C++. At least with exceptions, if you do miss one it will propagate out and you will know, with a missed return check, you may never find out.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2251521</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2251521</link>
				<description></description>
				<pubDate>Mon, 16 Mar 2015 06:49:31 +0000</pubDate>
				<wikidot:authorName>Daniel Kubec</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Perfect arthicle !</p> <p>Abstraction is a technique for managing complexity but these &quot;modern&quot; high-level features often results in more work for machine and developers without any additional values.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2240432</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2240432</link>
				<description></description>
				<pubDate>Thu, 26 Feb 2015 15:43:03 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>If I was to do that, I can as well use raw C, no?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2239987</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2239987</link>
				<description></description>
				<pubDate>Wed, 25 Feb 2015 19:54:22 +0000</pubDate>
				<wikidot:authorName>dawn</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>for exceptions, use std::nothrow or something like that.<br /> for init and deinit, use 2-phase ctor and dtor.</p> <p>code like this:</p> <p>XX* p = new(std::nothrow) XX(..);</p> <p>if (nullptr == p) { handle_error(); }<br /> else {<br /> auto ret = p-&gt;init();<br /> if (OK != ret) { handle_error(); }<br /> }</p> <p>if ( p-&gt;init_succ() ) {<br /> auto ret = p-&gt;deinit();<br /> if (OK != ret) {<br /> handle_error();<br /> }<br /> }</p> <p>&#8230;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2229959</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2229959</link>
				<description></description>
				<pubDate>Tue, 10 Feb 2015 22:35:54 +0000</pubDate>
				<wikidot:authorName>Corey Brenner</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>At a guess, you allocate the emergency buffer at the beginning of the program, and then bzero() it, writing the pages and bringing them concretely into your address space.</p> <p>From there, it's a matter of allocating from that particular pool (one of the reasons I think interfaces like malloc() are broken, is because there is no way to supply a generic pool of memory, or to seize a pool from malloc() and have it manage allocations within it).</p> <p>More sophisticated memory handling would benefit C.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2218616</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2218616</link>
				<description></description>
				<pubDate>Wed, 28 Jan 2015 11:19:09 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>The article is talking about idomatic C++ vs. idomatic C.</p> <p>If it was talking about C vs. C++ it would make no sense. C is (more or less) a subclass of C++.</p> <p>As for C++11, C++14 etc., by growing the featureset it's making the problem even more grave. Idiomatic C++ today is definetely a bigger mess than it used to be in 1995. Soon enough it will be as messy as Java :(</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2218447</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2218447</link>
				<description></description>
				<pubDate>Wed, 28 Jan 2015 06:53:32 +0000</pubDate>
				<wikidot:authorName>Rich</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>This point you make IS valid:</p> <p>&quot;This is great when you are OK with 80% or 90% solutions. Errors are sparse and handling them correctly in 90% or cases can mean the problem will be never hit, especially if the program is not used very widely.&quot;</p> <p>However, even a hello world application doesn't have a &lt;10% (we're sayingthat only 10% or less of the logic in the application doesn't handle every single error that can happen absolutely perfectly&#8230;) fault ratio; not even the UNIX kernel has a &lt;10% fault ratio&#8230;.there's always a way to break stuff, why fix it until it needs to be fixed? At which point you know the issue, and how to handle it&#8230;. I can hack Windows and activate it any day of the week -&gt; switching to another language isn't going to stop that.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2218436</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2218436</link>
				<description></description>
				<pubDate>Wed, 28 Jan 2015 06:33:44 +0000</pubDate>
				<wikidot:authorName>Rich</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I have to agree with others C++ is still a better bet, and to touch on Ilja's remark:</p> <p>Move to C++14, not to plain C. C++ i s an extension of C -&gt; You can use any part of C in C++ -&gt; including C syntax. In fact, most beginner C++ courses don't even teach you any C++ at all - it's all C syntax run under a C++ compiler. So in essence it doesn't even make sense to say C would have been better than C++&#8230;.</p> <p>The true trick to any lower level programming language is architecture. How you design your application will make it or break it -&gt; regardless of the actual language used.</p> <p>I'm disappointed seeing all the comments about replacement languages for C; why aren't people working on replacing POSIX APIs with C++ methods over C methods? Why isn't anyone working on replacing C altogether with C++ rather than just letting it be an extension? You know&#8230;making a true C++ runtime in Assembly instead of requiring a C runtime over Assembly? Bet ya that'd be much faster than Go and we wouldn't have to learn any new languages or APIs (well, for the most part - syntax would certainly change a bit for some system methods).</p> <p>Donate me 100k and I'll do it myself - just give me a few years&#8230;</p> <p>The father of C++ isn't dead yet, its only getting better and better and better and better and better.</p> <p>You just need to take the time to work it out. It takes YEARS to LEARN programming, not days -&gt; if you are looking for a single day answer switch to .NET or some other auto-generated non-sense and let the quality speak for itself (but I'm sure you know this already ^^).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2198031</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2198031</link>
				<description></description>
				<pubDate>Wed, 07 Jan 2015 00:57:15 +0000</pubDate>
				<wikidot:authorName>JoeF</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I know this is a very late comment but for what it's worth:</p> <p>Another alternative to is rust, being developed by Mozilla. It's focus is on being very fast and very safe. The first stable version is due to be released within the next few months and from the little bit I've played around with it, it looks promising as an alternative to C that can be used to build system programs that need to be robust.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2127793</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2127793</link>
				<description></description>
				<pubDate>Thu, 09 Oct 2014 07:08:26 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>That's the whole point. No additional &quot;high-level&quot; features that promote bad coding practices, i.e. separating the source of error from handling the error et c.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2127227</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2127227</link>
				<description></description>
				<pubDate>Wed, 08 Oct 2014 17:14:07 +0000</pubDate>
				<wikidot:authorName>Guy Alster</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>While I agree with the premise that C++ has features that are not adequate for every type of software project, I totally disagree with the conclusion that &quot;I should not have used C++ but rather C&quot;. First, lets state the obvious, which is that C is almost entirely a subset of C++. Hence, you could have still used the &quot;C&quot; semantics interleaved with the goodies that C++ gives you. To continue on that point, Since all programming languages are computationally equivalent, the choice of one language over the other is merely based on the semantics of that language. I would understand (but not agree with) the notion that you decided to use python over C++ because of the productivity gain (e.g. lines of code/hour) or perhaps the maintainability gain. But I just can't understand how using C makes your life easier compared to C++, besides the fact that the compiler restricts you to a certain subset of the features.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2113232</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2113232</link>
				<description></description>
				<pubDate>Fri, 19 Sep 2014 06:34:32 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes. See here: nanomsg.org</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2113230</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2113230</link>
				<description></description>
				<pubDate>Fri, 19 Sep 2014 06:31:43 +0000</pubDate>
				<wikidot:authorName>Ayub</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Did you actually write it using C instead of C++, will be interesting.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2053656</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2053656</link>
				<description></description>
				<pubDate>Tue, 17 Jun 2014 18:51:37 +0000</pubDate>
				<wikidot:authorName>Tim</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Interesting, Java is arugably the most diluted language ever. Not that Microsoft had anything to do with that, but still&#8230;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2053652</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2053652</link>
				<description></description>
				<pubDate>Tue, 17 Jun 2014 18:44:27 +0000</pubDate>
				<wikidot:authorName>Tim</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Late to the party, as always, but since I can still add my .02, I will. And I don't insist on these points, I believe that if you fall in love with a language and it meets your needs, go forth and multiply. But to Martin's objections I would raise these points:</p> <p>C++ Exceptions: Nothing is stopping you from using return codes in your app/system. You can infact turn them completely off with a command line option with some compilers, and simply not use them in the rest.</p> <p>Object Inititalizers: Use them where they make sense, and just use structs instead of objects for the rest of the cases and where the compiler-supplied constructors are not useful. The STL is pretty damn useful, I don't see the point of doing without it for the points you raised here. They are valid, but C++ is a buffet table, use what you want, ignore the stuff you don't.</p> <p>And to Adrian above: &quot;&#8230;This is the C way, but with a better standard library.&quot; Fine, but you don't explain how Go's &quot;standard library&quot; is better than C's. And by standard library, do you infact mean C's standard runtime library? Yes, I can agree with you that some of C's &quot;standard&quot; runtime libs are lacking, but you're not limited to using them. I do embedded programming and using GNU libc is usually not optimal in most cases, I often use eglibc and if I think C++ is a better fit for a problem I'll use uSTL.</p> <p>Go is a good language, a real contender as an all-around replacement for C in general for a compiled solution. But in the specific case of embedded programming, most of the companies I deal with will probably not even look at it for a long time, if ever. Aside from the support issues its still slower than C.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2030953</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2030953</link>
				<description></description>
				<pubDate>Tue, 13 May 2014 03:10:12 +0000</pubDate>
				<wikidot:authorName>yizhenfei</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Got it, thx :)</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2030717</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2030717</link>
				<description></description>
				<pubDate>Mon, 12 May 2014 19:01:20 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>There's no solution unless you want to keep a global repo of all intialised objects. It's doable but not particularly efficient.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2030662</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2030662</link>
				<description></description>
				<pubDate>Mon, 12 May 2014 17:20:34 +0000</pubDate>
				<wikidot:authorName>yizhenfei</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I have been troubled about the &quot;semi-initialized&quot; problem also.</p> <p>But I don't think C is the solution. Because in C++, if you don't want the &quot;semi-initialized&quot; state, you can choose not to use constructors and destructor. Writes Foo::init() and Foo::term() instead.</p> <p>The main reason &quot;semi-initialized&quot; state is introduced (at least for me) is that I want to ensure that when init() is called twice, init() can detect it and handle it gracefully (instead of possible memory leaking). And with the C version which allows random data in the struct, I cannot achieve this.</p> <p>What's your solution to prevent double initialization in C version of init() ?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2010680</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2010680</link>
				<description></description>
				<pubDate>Fri, 11 Apr 2014 10:39:37 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I wonder how is panic different from exception.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2010673</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2010673</link>
				<description></description>
				<pubDate>Fri, 11 Apr 2014 10:13:16 +0000</pubDate>
				<wikidot:authorName>Tomasz Sterna</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>There's more to life than C&#8230;<br /> <a href="http://blog.golang.org/defer-panic-and-recover">http://blog.golang.org/defer-panic-and-recover</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-2008880</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-2008880</link>
				<description></description>
				<pubDate>Tue, 08 Apr 2014 22:39:22 +0000</pubDate>
				<wikidot:authorName>weethomas</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>1. Bubbling up errors is contrary to the stated desire and requirements of the author. The more you bubble up an error, the less the handler knows about what actually went wrong.</p> <p>Common sense is not a contractual guarantee that an error could only happen one way.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1953080</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1953080</link>
				<description></description>
				<pubDate>Fri, 31 Jan 2014 19:59:47 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>How do you deal with memory overcommit?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1953053</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1953053</link>
				<description></description>
				<pubDate>Fri, 31 Jan 2014 19:35:17 +0000</pubDate>
				<wikidot:authorName>Roy Pfingsten</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Martin,<br /> Your remarks about no &quot;undefined behavior&quot; coincided with one of our servers, which has hundreds of gigabytes of memory, running out of memory due to a memory leak in Oracle.</p> <p>It prompted me to write something called tenacious_malloc(), which reserves some space (nominally 1MB) at the start of the program, which it uses as a pool to allocate memory from for other things that can't run out of memory. I hope you can make use of it, or maybe it will provoke further thought and development.</p> <p><a href="http://stackoverflow.com/questions/21172440/strategy-for-recovering-from-null-malloc-due-to-memory-exhaustion">http://stackoverflow.com/questions/21172440/strategy-for-recovering-from-null-malloc-due-to-memory-exhaustion</a></p> <p>Njoy!</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1935382</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1935382</link>
				<description></description>
				<pubDate>Tue, 14 Jan 2014 01:08:18 +0000</pubDate>
				<wikidot:authorName>Roy Pfingsten</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>PS: If you're thinking it would be nice to have an STL implementation for containers in C 2015, or whatever it would become, I'd 2nd that notion. It could just be a nice, tight lib that would become part of the C standard, which would make developing in small shops more comfortable as you wouldn't be introducing all kinds of custom solutions that you then have to try to recruit for to keep your codebase running.</p> <p>Just sayin&#8230;.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1935380</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1935380</link>
				<description></description>
				<pubDate>Tue, 14 Jan 2014 01:01:55 +0000</pubDate>
				<wikidot:authorName>Roy Pfingsten</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>If you read the MISRA C++,and JSF++ specs you'll find they exclude the use of try/catch as well - perhaps for the same reason. JSF++ was largely written by Stroustrup, so your analysis has some weighty endorsement.</p> <p>I was using the Lazy Pirate pattern in ZMQ, and noticed that even a single client sending a 32 bit int as data, and returning one from the lp_server stalled for 8-20 seconds at random times. I'm guessing that's the HWM getting hit, but it got me looking at Stream Control Transmission Protocol, which got me to thinking it would sure be great if some messaging primitives like ZMQ could be included in Linux. Good to hear that you have concluded the same it seems, and thus CrossRoads.</p> <p>I've been writing code for the VOIP industry the last 8 months, after years writing derivatives code for Wall St, and get the need for no &quot;undefined behavior&quot;. Also, we've been extending open source software like Kamailio with a hybrid of C &amp; C++, where the only part of C++ we use is the STL. Since these are generally watch-dog apps that monitor large Kamailio farms, linked by ZMQ, this is a very nice approach, as our staff's expertise is mostly in C, and encapsulation and polymorphism arising from the use of classes is just not needed.</p> <p>The one serious objection I have to C++ is it dropped anonymous structures, which was a horrible decision taken with very little deliberation. Without them maintenance on structs in code is much more difficult, and needlessly so.</p> <p>Best of luck on the CrossRoads project. That would be a real boon to Linux.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1894316</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1894316</link>
				<description></description>
				<pubDate>Sat, 16 Nov 2013 14:38:01 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Virtual functions are pretty easy to use in C as well. C++ has a slightly more convenient syntax, but it's not really a big difference.</p> <p>As for generics, yes, these are missing in C. It would probably make sense adding them to C, if the language was not completely ossified by now. There are macros though, which are somewhat less convenient to use, but more powerful at the same time.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1890718</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1890718</link>
				<description></description>
				<pubDate>Tue, 12 Nov 2013 08:02:09 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Nice analogy :)</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1889453</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1889453</link>
				<description></description>
				<pubDate>Sun, 10 Nov 2013 12:05:52 +0000</pubDate>
				<wikidot:authorName>Peter</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Nice post! I also read all the comments and I assume I will remember (because I'm a physicist) exceptions are &quot;actions at distance&quot;. Relying on such actions marks a physical theory as broken-by-design (like Newton's).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1884771</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1884771</link>
				<description></description>
				<pubDate>Mon, 04 Nov 2013 11:19:10 +0000</pubDate>
				<wikidot:authorName>fyy</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>It's the stage here that Foo behaves not like a c++ type.It's something bigger,needs several steps to build and may fail.There is no c++ feature to fit it.We can use constructors in other suitable cases.And I think the two core c++ features are the virtual functions and the templates.We can't get them from c.<br /> It's true c++ has many garbage,but we can get other benefits from it.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1884757</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1884757</link>
				<description></description>
				<pubDate>Mon, 04 Nov 2013 10:26:17 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>What's the point in writing code just to work around the features of the language? Why not use simpler language straight away?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1884755</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1884755</link>
				<description></description>
				<pubDate>Mon, 04 Nov 2013 10:05:32 +0000</pubDate>
				<wikidot:authorName>fyy</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>C++ is more than c and it doesn't means you must write code using every C++ feature.It's easy to solve your problem.<br /> 1 Do not use exception.<br /> 2 If you really want init,use it and KEEP THE CONSTRUCTOR EMPTY。example,<br /> class Foo<br /> {<br /> public:<br /> bool init();<br /> };<br /> Foo* f=new Foo;<br /> f-&gt;init();</p> <p>or you can use bool init_foo() directly</p> <p>If you really want term,use it and keep the destructor empty.<br /> f-&gt;term();<br /> delete f;</p> <p>If you really want Bar to inherit Foo,you can do it like this<br /> class Foo<br /> {<br /> public:<br /> virtual bool init();<br /> };<br /> class Bar:public Foo<br /> {<br /> public:<br /> virtual bool init()<br /> {<br /> Foo::init();<br /> }<br /> };</p> <p>think of this requirement in c,<br /> struct Foo<br /> {<br /> };<br /> struct Bar<br /> {<br /> Foo base;<br /> };</p> <p>bool init_bar(Bar* bar)<br /> {<br /> init_fool(&amp;base-&gt;base);<br /> }</p> <p>If c++ doesn't make things easier here,it doesn't make things harder.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1882262</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1882262</link>
				<description></description>
				<pubDate>Thu, 31 Oct 2013 08:06:29 +0000</pubDate>
				<wikidot:authorName>Timothy Qiu</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I think it's a matter of choice. (trade-off)</p> <p>Exceptions are idiomatic C++, and it is somewhat a &quot;standard&quot; way of handling constructor failures. It you choose not to use the exception feature, limiting yourself to a subset of C++, having to use workarounds/two-phase construction is the price to pay :(</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1882231</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1882231</link>
				<description></description>
				<pubDate>Thu, 31 Oct 2013 06:45:56 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes, but if you deliverately keep the constructor/destructor empty and create explicit init/term methods, why use C++ at all? To achieve your goal, you have to spend extra effort to avoid a feature of the language and write non-idiomatic code.</p> <p>I think the point of this article is not that C somehow allows you to do what C++ can't. That's nonsense, as C++ is superset of C. It's rather that when writing system-level code in C++ you often spend quite a lot of effort fighting the C++ features. The workarounds and non-idiomatic constructs also make code less readable.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1882229</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1882229</link>
				<description></description>
				<pubDate>Thu, 31 Oct 2013 06:40:11 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>That's the very point.</p> <p>Idiomatic C returns error code and you are expected to handle it immediately. To propagate it up the stack you have to do extra work (if (error) return another_error;).</p> <p>Idiomatic C++ throws an exception and propagate it up the stack automatically. You have to do extra work not to propagate it (catch (&#8230;) {&#8230;}).</p> <p>In other words, C encourages you to handle errors locally, while C++ encourages you to handle errors on higher level.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1882196</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1882196</link>
				<description></description>
				<pubDate>Thu, 31 Oct 2013 04:58:28 +0000</pubDate>
				<wikidot:authorName>Timothy Qiu</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>The &quot;semi-initialised/semi-terminated&quot; comparison is also unfair. Both the C++ and C versions have three states.</p> <div class="code"> <pre> <code>// C++ version foo theFoo; // into state A theFoo.init(); // into state B theFoo.term(); // into state C // C version struct foo *theFoo; // into state A foo_init(theFoo); // into state B foo_term(theFoo); // into state C</code> </pre></div> <p>They are actually the same.</p> <ul> <li>State A: You can call the `init` interface only, which gets you to State B.</li> <li>State B: Fully functional. Calling `term` interface gets you to State C.</li> <li>State C: Leave it alone. Calling `init` gets you to State B.</li> </ul> <p>The point of the state test in `foo::~foo()` is to check whether you called `foo::init()` and `foo::term()` before. You can/did not do that automaticly in the C version. If you want to achieve the same function, a state machine is also needed.</p> <p>For inheritance in this &quot;two step construction&quot; style, the initialization of parent class is like a normal member object. There is no need to combine the states.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1882119</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1882119</link>
				<description></description>
				<pubDate>Thu, 31 Oct 2013 02:23:23 +0000</pubDate>
				<wikidot:authorName>Timothy Qiu</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>As another approach, C++ equivalents.</p> <p>In the `if (rc != 0) handle_error();` example, since we are writing C++ equivalents, `fx()` should throw exceptions instead of error code too.</p> <div class="code"> <pre> <code>try { fx(); } catch (std::exception&amp; e) { handle_exception(); }</code> </pre></div> <p>As for the `if &#8230; handle; if &#8230; handle;` example: Why throw exceptions? C++ does not force you to throw exceptions. If you can test for `condition1` and you are determined to handle this condition, then handling it right there is a better choice.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1882110</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1882110</link>
				<description></description>
				<pubDate>Thu, 31 Oct 2013 02:06:33 +0000</pubDate>
				<wikidot:authorName>Timothy Qiu</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Your comparison of exception and return code is unfair.</p> <div class="code"> <pre> <code>int rc = fx(); if (rc != 0) throw std::exception();</code> </pre></div> <p>This code does not handle the exception, so it is not equivalent to</p> <div class="code"> <pre> <code>int rc = fx(); if (rc != 0) handle_error();</code> </pre></div> <p>Instead, it is equivalent to</p> <div class="code"> <pre> <code>int rc = fx(); if (rc != 0) return generate_another_error_code(rc);</code> </pre></div> <p>So, you have no idea of who and where is going to handle the error either.</p> <div class="code"> <pre> <code>class exception1 {}; class exception2 {}; try { ... if (condition1) throw my_exception1 (); ... if (condition2) throw my_exception2 (); ... } catch (my_exception1 &amp;e) { handle_exception1 (); } catch (my_exception2 &amp;e) { handle_exception2 (); }</code> </pre></div> <p>The above piece of code is not equivalent to this either:</p> <div class="code"> <pre> <code>... if (condition1) handle_exception1 (); ... if (condition2) handle_exception2 (); ...</code> </pre></div> <p>The C equilvalent should be something like:</p> <div class="code"> <pre> <code>int foo() { ... if (condition1) return ERROR_CODE_1; if (condition2) return ERROR_CODE_2; ... } switch (foo()) { case ERROR_CODE_1: handle_exception1(); break; case ERROR_CODE_2: handle_exception2(); break; default: assert(0); }</code> </pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1881550</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1881550</link>
				<description></description>
				<pubDate>Wed, 30 Oct 2013 13:23:23 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>In C I would do the following:</p> <div class="code"> <pre> <code>int myclass_init (struct myclass *self) { ... }</code> </pre></div> <p>How is the solution with private constructor and a construct method and handling of exceptions simpler than that?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1881547</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1881547</link>
				<description></description>
				<pubDate>Wed, 30 Oct 2013 13:20:07 +0000</pubDate>
				<wikidot:authorName>Hannes Steffenhagen</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Erm - I'm not going to disagree with everything you've said here, but for the constructor part&#8230; you could just solve that problem by making the constructor private, something like</p> <p>class XYZ {<br /> private:<br /> XYZ();<br /> public:<br /> static XYZ construct(int&amp; error_code);<br /> };</p> <p>You just do the exception handing in one place (the construct method), and never have to worry about it again. Obviously you'd have to treat copying and assignment in a similar fashion, but that's no different in C. This does make constructing objects slightly more awkward than it would normally be in C++, but not really more than it is in C.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1873804</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1873804</link>
				<description></description>
				<pubDate>Sat, 19 Oct 2013 08:13:58 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Typically it works like this:</p> <p>rc = fx ();<br /> if (rc == 0)<br /> do_something();<br /> else if (rc == EINVAL)<br /> do_something_else ();<br /> else<br /> assert (0);</p> <p>You handle only the errors you are aware of (check the documentation of fx function). Everything else is considered a fatal error. Note that exceptions work in a similar way &#8212; unhandled exception causes program to abort.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1870558</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1870558</link>
				<description></description>
				<pubDate>Mon, 14 Oct 2013 10:36:08 +0000</pubDate>
				<wikidot:authorName>todd_wang</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>a C function &quot;foo&quot; returns an error code, let say it is an integer, there will be 2^32 possibilities, will you write 2^32 lines of &quot;if(error == n) handleErrorn();&quot;?<br /> if not, how do you know that you don't miss some new defined error code? i.e. someone changed the foo function and add some new error code?</p> <p>to me, it has nothing different with adding a new type of exception in c++.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1835794</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1835794</link>
				<description></description>
				<pubDate>Mon, 19 Aug 2013 08:38:20 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>This is actually unlike about C++. All the time I am getting to the situation where I have to write extra code (the macro in this case) just to get rid of C++ features. I rather use a language that lacks the features in question in the first place.</p> <p>As for C, I've already re-written ZeroMQ in C (see nanomsg project) and the code is simpler, more readable, behaviour is fully defined etc.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1835793</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1835793</link>
				<description></description>
				<pubDate>Mon, 19 Aug 2013 08:34:19 +0000</pubDate>
				<wikidot:authorName>Martin Sustrik</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>By exponential growth of complexity I meant that exceptions are propagated up the call stack and thus each single exception can end at approximately N^M places where N is average number of calls per function and M is average depth of the call stack. There's no way you can make sure that all those codepaths behave in sane manner.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1833924</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1833924</link>
				<description></description>
				<pubDate>Fri, 16 Aug 2013 11:40:35 +0000</pubDate>
				<wikidot:authorName>Walt Howard</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Sigh.</p> <p>Exceptions are just big returns. And the catch block is the call point.</p> <p>You should have ONE exception class in your project, subclassed from std::exception. In that class you have members that hold the OS error code, an application specific error code, and a string that describes the error and possibly the file and line where the exception was thrown.</p> <p>At the catch point you can decide how to handle the problem. In 95% of these things all you need to do is keep running, possibly logging a warning or error.</p> <p>If you are down on exception syntax create a macro</p> <p>#define IFTHROW(CODE) try { CODE } catch</p> <p>That will act just like an old fashioned &quot;if (err no)&quot;</p> <p>If you think C++ causes undefined behavior, just wait until you use C.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1833857</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1833857</link>
				<description></description>
				<pubDate>Fri, 16 Aug 2013 08:14:38 +0000</pubDate>
				<wikidot:authorName>Pablo</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I think you should consider using scope_guard with lambdas, and std::optional&lt;T&gt;&#8230;</p> <p>I don't remember the last time I used exceptions without scope_guard, but I remember the pain, which is pretty similar to what you describe.</p> <p>IMO this problem is not new, its 10-15 years old, lots of solutions to this problem exists. scope_guards + lambdas make the code better than in C. std::optional makes the code _WAY_ better than in C. There are other idioms like Expected&lt;T&gt;. So instead of complaining that old style c++ exceptions are a pain you should move to new-style exception handling.</p> <p>The problem with exponential code growth that you describe has nothing to do with c++ at all. It basically means that your hierarchy of exception classes is wrong. Instead of adding new catch classes to handle different exceptions types in the same manner, you should have fixed your exception class hierarchy. If you really do need to handle the exception differently, then yes, you need the extra code, and that code will be there if you translate your program to C.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1833528</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1833528</link>
				<description></description>
				<pubDate>Thu, 15 Aug 2013 21:18:35 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>To be frank, I believe that the whole concept of inversion of control is one of the more horrible ideas to be found in computer science. Just to give an example why it's problematic: My domain-specific code can happily use two libraries. However, would you ever dare to embed your domain-specific code into two frameworks in parallel?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1833515</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1833515</link>
				<description></description>
				<pubDate>Thu, 15 Aug 2013 21:02:40 +0000</pubDate>
				<wikidot:authorName>Artur Ortega</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>When reading through the described problem it feels like, you are looking for &quot;inversion of control&quot;, e.g. <a href="http://code.google.com/p/iocc/wiki/GettingStarted">http://code.google.com/p/iocc/wiki/GettingStarted</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1809307</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1809307</link>
				<description></description>
				<pubDate>Fri, 05 Jul 2013 09:34:45 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes, the nice thing about exceptions is that they actually force the user to handle them. Same doesn't apply for error codes. User is free to ignore them.</p> <p>However, exceptions are still bad because of decoupling the error and the error handler, as described in the article.</p> <p>If I was designing a new language I would go for error codes and made it mandatory to handle them.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1809306</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1809306</link>
				<description></description>
				<pubDate>Fri, 05 Jul 2013 09:27:58 +0000</pubDate>
				<wikidot:authorName>xieyong</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>In my opinion, you are right use return value for err which can deal quickly. the exceptions is usefull when you write a library,other one use your functions and he can deal some err in your functions , you do not know how he can do, so you can throw exceptions . if the user do not deal err,he will die ,and use exceptions info find the place.if only return err value,he may do not use it, so he may find problem at other place,hard to find where is real err. so exceptions is usefull for interface for other people ,return value to deal with youself.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1806378</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1806378</link>
				<description></description>
				<pubDate>Sat, 29 Jun 2013 18:20:05 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Kjell, thanks for the favourable comment!</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1806377</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1806377</link>
				<description></description>
				<pubDate>Sat, 29 Jun 2013 18:00:04 +0000</pubDate>
				<wikidot:authorName>Kjell Hedstrom</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Very interesting read. C++ (and C) can be so completely different depending on one's background and different coding culture that shape one's coding style. Lately the C++ community is relearning (about time) as C++11 becomes mainstream.</p> <p>I have done mostly C++ for the last 12 years. Focus were on safety-critical software. I must say that I have almost never used exceptions. They are pretty much banned in safety-critical and real-time systems.</p> <p>In fact the error handling you say is the &quot;C&quot; way of handling errors is to me just one way to handle errors. Which in fact is the real power of C++ to me. That you can choose different programming styles and paradigms.</p> <p>Interesting read! I would not make the same conclusion myself as you did but either way I truly enjoy ZeroMQ and think it is an amazing library.</p> <p>Cheers<br /> Kjell</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1726913</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1726913</link>
				<description></description>
				<pubDate>Fri, 08 Mar 2013 23:10:59 +0000</pubDate>
				<wikidot:authorName>Anton Daneyko</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Sorry for the off topic. Why do you use struct states to define the enum type rather than defining it inside of the struct error? What does it buys you?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/forum/t-467476#post-1661601</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/forum/t-467476/why-should-i-have-written-zeromq-in-c-not-c-part-i#post-1661601</link>
				<description></description>
				<pubDate>Thu, 20 Dec 2012 09:06:03 +0000</pubDate>
				<wikidot:authorName>Iain Hull</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I Largely agree with your points that exceptions make large code bases brittle. You need to have very well defined boundaries between subsystems where only a small subset of exceptions can travel across. However proving that your code follows this pattern is not easy.</p> <p>I agree that return codes are beter than exceptions most of the time, but thing they require some syntactic sugar in the language to remove the tons of extra boiler plate code that results where every function call has to check the previous one succeed before making the call.</p> <p>I strongly disagree about init and cleanup methods, they are never a good idea, all objects should be valid and meet their invariants after construction, period. If you don't want exceptions but do want constructors to be able to fail then either use a static factory methods or the builder pattern. Both solve the same problem, verifying the preconditions of your constructor are met and only returning a valid object. One does tries and asks for givenness and the other ensures it will work then only tries once it knows (both use a</p> <p>// using char and raw pointers to keep example as simple as possible<br /> class Foo {<br /> Foo(const char * inFile, const char * outFile) {<br /> // could fail but will only throw FooException<br /> }</p> <p>public:<br /> static Foo * create(const char * inFile, const char * outFile) {<br /> try {<br /> new Foo(inFile, outFile);<br /> } catch (FooException &amp;) {<br /> // handle exception here<br /> // this is the only place where exceptions are thrown or caught<br /> return 0;<br /> }<br /> }<br /> }</p> <p>or with builder</p> <p>FooBuilder fb = FooBuilder().inFileParam(&quot;some path).outFileParam(&quot;some other path&quot;);<br /> if (fb.canBuild()) {<br /> Foo * = fb.build();<br /> }</p> <p>Regarding destructors and exceptions i feel if there is a chance you could throw in a destructor the class is probably doing to much, part of the class' state belongs in a function.</p> <p>Scala has introduced a nice why to handle exceptions with there scala.util.Try&lt;T&gt; class, this is a generic type that holds a value or an exception. So any function that can fail returns a Try&lt;T&gt;. the exception holds any information that might be required about what happened. If you use closures the Try can provide two methods so safely deal call functions on your code.</p> <p>template &lt;typename T&gt;<br /> Class Try {<br /> boolean hasValue();<br /> boolean hasException()</p> <p>template &lt;typename R&gt;<br /> Try&lt;R&gt; map(std::function&lt;R(T)&gt;); // For functions that don't fail</p> <p>template &lt;typename R&gt;<br /> Try&lt;R&gt; flatMap(std::function&lt;Try&lt;R&gt;(T)&gt;); // For functions that could fail<br /> };</p> <p>Try&lt;string&gt; hostaddress = &#8230;<br /> Try&lt;Socket&gt; socket = hostaddress.flatMap(resolveAddress);</p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>