19 ms·
Why should I have written ZeroMQ in C, not C++
- nirvana 14y ago"First, it's important to take into account that ZeroMQ was intended to be a piece of infrastructure with continuous uptime. If should never fail and never exhibit undefined behavior." There is one language/platform[1] I'm aware of designed for this type of system, and which achieves it beyond all others: erlang. If Uptime is important, how do you handle it when you want to update your software under C++ or C? You have to bring the service down. Erlang supports updating software while its still running. If exception handling is important (to prevent crashes) how do you handle it when there is a bug? Erlang has supervisors that not only help you manage exceptions but keeps the service going when an unhanded exception causes things to crash. More importantly, intrinsic to the nature of the way you write erlang code, you eliminate a great deal of the possible errors. In C code you have to check to make sure things are in the right state while running your code. In erlang, your code doesn't run (the function isn't called) if the state isn't right to handle it. It flips this problem eliminating many classes of errors. Further there is OTP support for many types of processing (like state machines) that makes writing these types of solutions much easier. Erlang is great for making sure no undefined behavior happens. Erlang is also great (as I understand it, this I haven't gotten into) for creating unit tests that can fully exercise the code across all possibilities. Where does erlang suck? I don't think it sucks anywhere because it has solutions for all of its own problems. For instance, single node performance of an erlang program (which runs in the BEAM VM) is going to be lower than single node performance of a C program... but in erlang you can increase capacity nearly linearly simply by adding more nodes... while this is nearly impossible with almost all C/C++ programs without spending a lot of time working on it. But where erlang is weak is that single node performance which might be really important[2], and if it is, you can then write your performance critical bits in C. Thus the things that do the real work can be fast and in C but the things that keep the system going and distributed (where performance of this kind is much less critical, but performance of the operational kind is paramount) can be written in erlang. So, I think the second mistake he made, and is still making, is thinking that the project has to be written in a single language. If you use the best language for the job, then sometimes that should mean using two languages right? Erlang is not a hipster language. No hipsters use erlang. It is 25 years old and boring and %99.9999999 uptime. Its ugly. Its not hot and fresh and new. But it is the right language for the job, when you've got a system that need to run across cores or nodes, or have very high uptime. And really, it doesn't take but a couple weeks of learning. Then the syntax will be gorgeous and you'll be a better programmer for it. [1] I say "I'm aware of" for a reason. There may be others as well suited when this is the primary goal, possibly even better suited. I don't know all languages. But I do have a pretty good survey started in the days when new languages were as common as YC batches and much more experimental than they are now. My point isn't to bash other languages but to promote one that isn't understood correctly by many people. [2] I think this is the case a lot less often than people think. People benchmark things on a single node even when they know they are going to build a cluster of machines to run them, and then pick them based on this. Redis is really fast. Is redis distributed? Riak has a fully distributed in memory database (which means 10 32GB nodes means you can store 320GB in RAM if you want, rather than have 10 nodes all storing the same data in a cache, and thus much less data cached for the same number of machine with something like Redis.
- alexchamberlain 14y agoIf Uptime is important, how do you handle it when you want to update your software under C++ or C? You have to bring the service down. Erlang supports updating software while its still running. Nginx has a hot update feature and is entirely written in C.
- rumcajz 14y agoThe article is about undefined behaviour. Erlang won't help much with that.
- gaius 14y agoWell, yes and no. I know more about OCaml than Erlang, but pattern matching and guards let you be very sure that a function is going to handle every possible input, and static typing means all code paths can be verified at compile time - there's no way into or out of a function without the program being in a valid state.
- pmjordan 14y agoThis strikes me as throwing the baby out with the bathwater. While the criticisms are valid, and people love to hate C++ for all sorts of reasons (I avoid C++ exceptions altogether), C++ is for practical purposes a superset of C, so if a C idiom works better than its C++ equivalent, you can just use it instead. I've been working on a project which has necessarily been written mostly in pure C (kernel code), and I do really miss C++'s extra type safety. (GCC has some type warnings that help, but it's still not as safe) Then again, maybe an entirely different language, geared towards high availability, such as Erlang or Ada, might have been a better choice in the author's case.
- rumcajz 14y agoYes. C syntax compiled with C++ compiler is a reasonable option. The question is whether it deserves being called C++ then.
- figglesonrails 14y agoYes, it does, for the same reason that C++ code that is compiled with a C compiler can be called C.
- rubashov 14y agoYeah, just don't use virtual methods or constructors on classes and his second complaint pretty much goes away. And you get a syntax and amenities that are still way nicer than C.
- beothorn 14y agoThis ^ If a language feature doesn't work for you, you don't need to use it. In this case not using it is writing c, but this is true to every program language. When I use a oo language I always use composition and ignore inheritance. Unfortunately you can't avoid dealing with those complexities if you use a library, but if the advantages of using a language/platform outweighs the advantages, is awlays possible to work around it.
- rubashov 14y ago
- latch 14y agoThe background made that post unreadable for me. Minimalism done wrong.
- shin_lao 14y agoIt looks mainly looks like a rant on exception, but nothing forces you to use exceptions with C++. You can even allocate memory in a way that doesn't throw. We don't use exceptions for the reasons described in the article (and many others), we use boost::system::error_code instead. But that's for the first half of the article, and the OP admits that he simply gave up on exceptions. As for the part about half-initialized state, I think the problem is that the author is trying to do OOP in C++ without exceptions. Perhaps a more generic programming approach would solve his "half initialized problem". Don't want to sound like a snob, but it really looks more like a design problem than a language problem.
- vz0 14y agoI agree, this is just a rant on C++. Coming from Java world, I can tell that it is nice being able to raise exceptions from the constructor. However, switching from C++ to C is absurd. C++ is (mostly) a super set of C. Whatever you want to do in C, in C++ is also possible. If there are some C++ features (exceptions, classes, contructors, etc.) that are making his coding task more complicated, he should simply stop using those features and refactor his code.
- ufo 14y agoThere is one advantage to writing in plain ANSI C and it is that you get it to compile and run on anything.
- antidoh 14y agoI wouldn't say absurd. Certainly you can use C functions in C++. But if you want to eliminate the use of most or all C++-only features, the only way to guarantee that is to not use C++. White or blacklists can be circumvented, intentionally or inadvertently.
- dbcfd 14y ago> Don't want to sound like a snob, but it really looks more like a design problem than a language problem. I stopped reading about halfway through as most of the code samples reinforced this.
- wladimir 14y agoExceptions are indeed not the silver bullet to error handling. Handling errors upstream can be useful as catch-all, but when the entire stack has been unwound, it can be hard to recover the error usefully. Also it is hard to make a sensible inheritance hierarchy, and every library chooses its own, generating a forest of different-but-equivalent exceptions to handle. A fully-fledged condition system (like Smalltalk, CL) would allow for a lot of scenarios where exceptions currently give trouble. They would allow recovering the problem where it happens, retrying operations, and so on. Too bad so few languages have that. However I don't think the right solution is to use an even more primitive language. C seems simple, but you end up doing everything yourself that would otherwise be done by the compiler, which is a lot more work, bug-prone, makes the code verbose, and generally inconsistent (unless you're very disciplined; forget about it in a team).
- Meai 14y agoThat's awesome, I'm already looking into crossroads-io. I like C because it's that much more readable: There is no magic, you always know where things are and where they are going, in terms of memory and control flow. C++ seems very convenient at first, all the nice standard libraries do have attraction for me but in the end you end up with tons of weird hierarchy magic, friend classes, nested classes, copy constructors and destructors firing at the weirdest places. Now everybody says: "Well you don't have to use those!". Well, true but in practice it doesn't turn out that way.
- erichocean 14y agoIf you're enough of an expert in C++ to use it in failproof ways, then you're enough of an expert to do the same in C, and with far less mental overhead for yourself and everyone who comes after you to read the code.
- xxiao 14y agoon the exception handler part, i don't think you're forced to use c++'s try-throw-catch, you can still safely use the C-style exception methods, after all, c can be used as a subset of c++, though not 100% of the time.
- losethos 14y agoGrep("File::Read");
- pkmays 14y agoI'm not C++ savvy, but I know from reading Google's C++ style guide that they also disable exceptions. The guide leaves it at that and doesn't say anything more about how to deal with errors. Does anyone here know how these big Google C++ codebases handle errors instead?
- andyjohnson0 14y ago[The following is speculation: I have no access to Google's code.] I can't think of any other way to handle errors apart from using return values. Methods return error codes which are handled by the caller or bubbled-up to its caller. This tends to result in lots of duplicated error handling code, and you have to either dedicate the return value to success/fail (which means you have to return non-status data some other way) or use special values to indicate failure. The Go language (from Google) doesn't have exceptions and allows functions to return a value and an additional error return value [1]. I'd guess that this is inspired by their approach to C++ coding. [1] http://code.google.com/p/go-wiki/wiki/Errors http://code.google.com/p/go-wiki/wiki/Errors
- rb12345 14y agoIsn't it possible to fake this with C++ templates? As an example, I created https://github.com/rb12345/cpp_annotated_return https://github.com/rb12345/cpp_annotated_return, which uses a templated struct to allow multiple value returns.
- andyjohnson0 14y agoYes, you could do it that way. Personally I'd restrict the error code to always be an int, which makes for a terser syntax as you don't need the second template parameter. You could also extend it to support multiple non-error return values, like Python does. But this introduces problems with expressing the contract between caller and called (e.g. [1]) and I think the best way to address this might be to extend the language syntax. I think one of the most interesting design choices in Go is that it intentionally omits conventional exceptions. It does have defer/panic/recover [2] though. [1] http://stackoverflow.com/questions/354883/how-do-you-return-multiple-values-in-python http://stackoverflow.com/questions/354883/how-do-you-return-... [2] http://blog.golang.org/2010/08/defer-panic-and-recover.html http://blog.golang.org/2010/08/defer-panic-and-recover.html
- cageface 14y agoI really think the final nail in C++'s coffin is going to be its refusal to play ball in a polygot world. Most languages let you drop down into C pretty easily but C++'s weird name mangling, exceptions and complex, usually nonstandard ABI makes interfacing with C++ a major PITA. In the days when C++ was used soup-to-nuts this wasn't such a big deal but these days you almost always want some kind of higher level language on top. Just look at all the contortions WinRT has to go through to expose its APIs versus the clean Foundation/Cocoa layering you see in iOS/OS X for a great example.
- supar 14y agoI agree. In fact, this is what I would have expected to read in the article. The only single major issue in creating infrastructure in C++ is the enormous added complexity in the final library and dependencies. While you can avoid mangling and support a "C" api by using ``extern "C"'' declarations, this mostly imposes a "c" like, no-oop API that doesn't really save much work compared to a "C" api.
- gaius 14y agoCertainly in my own projects I have found that going OCaml<->C<->C++ with extern is infinitely more fun than trying to go OCaml<->C++ with SWIG.
- calloc 14y agoAt least with clang/llvm and gcc you now have binary compatibility between two competing compilers. You can take a .o built with gcc (g++) and link it with a .o generated by clang (clang++) without issues. Same name mangling, same everything. This means that I on my system at least don't care anymore whether the project is built with GCC or with clang and I can use either or for my own projects. The thing though is that the C++ standard doesn't have a default ABI, so saying that it is non-standard isn't even the case, that we get any compatibility is nice at all, and I understand that complaint. The biggest issue I've ran into is that even with the same compiler on the same platform (using MSVC 2008) setting different compiler flags generated completely different code and memory layouts for std::vector that caused me to not be able to link against a DLL. At least some consistency exists with other compilers and different flags don't necessarily change compatibility. I don't think it is entirely fair to compare WinRT with Foundation/Cocoa. WinRT has an entirely different goal than what Foundation/Cocoa provide, and Foundation/Cocoa provide none of the same things that WinRT provides such as a object model that can be used across different programming languages fairly easily. Mac OS X has nothing that even comes close to COM.
- evincarofautumn 14y agoThis is absurd. Exceptions are just generalised returns. You can use them well and benefit from them, or use them poorly and make the stuff of nightmares. It’s the same with any feature of any language. You can choose not to use exceptions in your code, if that makes it easier for you to understand and manage, but it’s certainly not the fault of the feature in general. Basically, it’s up to you to structure your code well. Yes, it gets bad if a potentially throwing function can be called from multiple points. The error needs to be handled at every one of those points, and probably in much the same way. But if you see repetition, why aren’t you factoring it? And why are you calling that function from multiple unrelated locations in the first place? I get it. I’ve used C++ for half a lifetime—it’s a hopelessly broken language. There are tons of things about it that just make me furious. But I can get stuff done in it because I’ve taken the time to understand it in depth. Don’t complain about the language or a particular feature thereof just because it’s not suited to your problem or your way of thinking. There are other languages out there (Erlang) that are far better suited to stable zero-downtime systems than C++. There are languages (Haskell, Lisp) that help you better manage complexity than C++. Every language implementation worth its salt has C bindings, so you can write performance-critical code at a low level, while still managing the whole system in a high-level language. There are options. Explore them!
- mccoyst 14y agoOne of his first examples is additionally absurd and is either the flimsiest of strawmen or he simply doesn't understand when exceptions should be used: try { ... int rc = fx (); if (rc != 0) throw std::exception ("Error!"); ... catch (std::exception &e) { handle_exception (); } Why is he throwing exceptions and catching them within the same function? His "C equivalent" is what he should've been doing in C++.
- onli 14y agoHe states how he understood exceptions: "C++ exceptions just didn't fill the bill. They are great for guaranteeing that program doesn't fail — just wrap the main function in try/catch block and you can handle all the errors in a single place." This is something i learned in my very first computer science lecture not to do. To be fair: It's what exceptions can be good for - a last barrier before a crash and a way to handle errors later. But you're absolutely right that he simply could react directly to the error. Or throw specific exceptions and react to them. His described issue has nothing to do with exceptions themselves, just with the way he thinks he has to use them.
- aidenn0 14y agoThis describes quite well why I strongly recommend against exceptions in embedded code. There are ways that you can use constructors, one way is to have an error-code as part of the object that the constructor can set. Another way is to use the empty-constructor/init-method pattern that he talks about and wrap it in a static method (or function) and that becomes your actual constructor. I think you can even make the constructor private which will prevent accidental calling of it. But this is just another example of why high-reliability systems require considerably more discipline in C++ than in C, since C++ gives you more rope, it's easier to hang yourself. There is an argument that such a limited dialect of C++ is so close to C (with a good 3rd party data-structures library) that there is no point to C++ in such situations (which seems to be the point the article is making), and I tend to go back and forth on this.
- dustingetz 14y agoI wonder what error-monad looks like in C++, or C for that matter. here's a rough, probably incorrect demo in python: https://gist.github.com/2653752 https://gist.github.com/2653752 gives you nice, clean, exception-like error handling that doesn't leak to the wrong level of the call stack, and in a statically typed language the compiler can verify your error handling for you. quite similar to checked exceptions. call stack issues can be fixed with some low level C, or you could even unwind the stack with some exception trickery.
- crawshaw 14y agoFor careful error handling, my favorite language is Go. It lacks exceptions, so you have to return errors as in C. But it has python-style tuple return, making it easy to return a value or an error from any function. The fact that errors are explicitly returned requires the programmer to explicitly handle them, which encourages design that considers error handling. The evil of exceptions is they hide errors until they happen.
- Locke1689 14y agoGoing forward, I think C++ is not a bad choice, but I can definitely see the distaste for exceptions. Unfortunately, as the author notes, simply not using exceptions doesn't quite do it. Fortunately, the hard work has been done for you. Much of Google's code was written in an exception-free manner before newer evolutions of C++ came out. This means that they have banned use of exceptions in their style guide. Luckily, it also means they've developed workarounds for most of the exception pain points. I would encourage everyone to take a look at the Google C++ style Guide[1]. Most of the complaints are addressed in that article. Constructors can only signal errors through exceptions, so Google C++ allows only basic initialization in the constructor -- all real work is done in an explicit Init() method which can signal an error. I believe the guide addresses the posters other concerns too. In general, the Google C++ style guideline is a very good resource for writing consistently good C++. [1] https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml https://google-styleguide.googlecode.com/svn/trunk/cppguide....
- drucken 14y agoAgreed, it is a very good guide. However, the ZeroMQ author goes a lot further than that for his specific application. He made some reasonable arguments that even the use of OOP/classes in C++ makes catching undefined behaviour unnecessarily difficult for systems programming.
- Locke1689 14y agoHis other objections didn't make a lot of sense to me. Destruction doesn't seem like something that can fail. Your object has been deleted or it is going out of scope. You don't even manually call the destructor. It should be about freeing resources. what work is he doing in the destructor that can fail?
- gchpaco 14y agoWell, fclose can fail, for example; it can as part of the closing process flush its buffer and that can fail like any other I/O process. Further, sometimes the error than happened during a previous write(2) call is only detected in the close(2); think NFS and quotas, or check the man page. So already we have errors that occur during teardown that need to be handled somehow. Similarly one can imagine using RIAA to hold a file lock, or a temporary directory; this is a perfectly reasonable thing to do but there are dozens of reasons why the final rm -rf of the tempdir could fail. The idea that somehow object teardown is immune to failure is overly naive, and the fact that you can't accommodate it easily in RIAA is quite disappointing and makes the whole paradigm much less useful for carefully coded software.
- pwpwp 14y agowat?
- haberman 14y agoI struggled with a similar question for my low-level protobuf library UPB (https://github.com/haberman/upb https://github.com/haberman/upb). Here are some blog posts describing my dilemma about this: http://blog.reverberate.org/2009/11/porting-upb-to-c.html http://blog.reverberate.org/2009/11/porting-upb-to-c.html http://blog.reverberate.org/2009/12/torn-over-c-question.html http://blog.reverberate.org/2009/12/torn-over-c-question.htm... I ultimately chose to stick with C, and I'm happy with my decision. When people ask me why I stuck with C, it's difficult to give a single overwhelming reason why C is better. The most clear-cut one is that C++ is not supported in the Linux kernel and I want my library to be usable there. But the other reasons why I prefer C are not as easy to quantify. One reason is that code written in C is more transparent. You can look at some C and know what it is going to do (add some numbers, call a function, etc). Macros are the one exception to this, but good C programs use these sparingly and clearly mark the macro with an UPPER_CASE_IDENTIFIER. C++ is much harder to "see through." Any function call could end up throwing an exception which does a non-local exit from the function. Any addition, assignment, pointer dereference, etc could actually be an overloaded operator. Any function call could be performing a user-defined implicit conversion on any of its parameters. For overloaded functions, the compiler decides what function is actually called by applying non-trivial pattern matching rules. The runtime will automatically invoke any static initialization code (like constructors of global statics) pre-main in an undefined order. etc. etc. I intend to get a thorough security review of my library once its design stabilizes. I asked Tavis Ormandy (a fellow Googler and security badass) which language is easier to audit for security and he said C for the reasons of transparency I listed above. People often say that you can just avoid using the parts of C++ that you don't like. That is true, but hard to enforce, especially on a multi-person project. If you're asking others to follow your set of rules, you have to write those rules down in meticulous detail, leading to something like the Google C++ style guide (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...), and at that point you're asking your contributors to study and internalize a large and complicated list of what is and isn't allowed just for the privilege of contributing to your project. I don't think this approach scales to lots of projects that are all choosing a different subset of C++. There are definitely things I miss by not having C++'s facilities. Constructors and an implicit "this" parameter are both really nice. Constructors are remarkable in that you can write a single function that gives you three different construction patterns for free (direct construction, heap construction with "new", construction in an arbitrary location with placement new). Automatic upcasts are nice and totally safe. Inheritance and public/private specifiers let you express directly lots of things you can only express with comments in C. But overall I think that using straight C is the right choice for a project like my library UPB.
- st3fan 14y agoInteresting read but the problem is not C++ here. The problem is the author's usage of C++ and specifically exceptions. If he does not like exceptions then just implement more traditional error handling while keeping all the other good things that C++ provides.
- HardyLeung 14y agoThe reasoning is very poor. I thought he was going to say something along the line of portability. Nope. It was about exception. Granted, exception is problematic. I don't use exception for similar reasons. However, given the nature of this project, it should have been clear that exception should not have been used in the first place. Instead, be very explicit about error handling. This is really a poor design choice. How is it the conclusion that the answer is C, rather than "C++ without exception?".
- Suncho 14y agoIn C++, if you run into an error and you know how to handle it, you handle it. This is exactly the same as C. Exceptions are only there for when you don't know how to handle an error. Instead of calling exit(), you throw an exception and hope that someone further up the stack can do something useful. By default, your program terminates, just like exit... but all your destructors get called, so you don't leak database handles or locks or other resources. Nice. I've read the Google C++ style guide and it's basically a joke. At least it was a joke two years ago. The guide even contradicted itself in multiple places. Google bends over backwards to avoid using exceptions and the result is that C++ isn't C++ anymore.
- alpatters 14y agoI agree with this entirely. Exceptions and errors aren't necessarily the same, i.e. errors aren't always exceptional cases. When errors can be dealt with locally they should be. The problem comes when an error can't be dealt with locally. Then as stated, exceptions can be used to propagate the condition upwards in the stack where some other component may be able to deal with it.
- vph 14y agolooking forward to crossroad i/o. This step will drive the two projects even further apart. But zeroMQ is already established, and its name is more catchy. Good luck.
- vz0 14y agoGCC is finally switching from C to C++, and they are actually avoiding exceptions and RTTI. http://gcc.gnu.org/wiki/CppConventions http://gcc.gnu.org/wiki/CppConventions I salute them on following strict coding conventions.
- RandallBrown 14y agoThis may just be because of when I learned to program, but I find that writing object oriented code makes everything easier to understand. The stuff you need to do with C where you're passing around structs and state and pointers usually looks pretty ugly to me. Error handling is a pain in any language. "This thing that should NEVER fail just failed, now what?" If you're not in a recoverable state, realistically, what can you do? I know that constructors can fail, but it's pretty abnormal for that to happen. I like the way objective-c handles it. Since everything is dynamically allocated and you can just see if the object exists to find out if it works. Lots of methods have an extra NSError parameter that you can use if you need more information.
- ltratt 14y agoI agree fully with the author - exceptions are a problem for software that wants to avoid unexpected behaviour. I noted something similar in http://tratt.net/laurie/tech_articles/articles/a_proposal_for_error_handling http://tratt.net/laurie/tech_articles/articles/a_proposal_fo... and sketched a possible compromise, more to emphasise the point, than as a serious proposal.
- ecopoesis 14y agoExceptions shouldn't be used as gotos. Instead of letting every exception bubble to the top, handle them at the appropriate level in the stack where you can recover from the error they representing.
- gruseom 14y ago90% of this thread isn't addressing his core point, which is that even if you use C++ without exceptions, constructors and destructors still make it hard to be strict about error handling, and the extra complexity isn't worth it for projects like his. Fine to disagree, but respond to the point. So far the relevant objections I've seen are: (a) you shouldn't do anything in a constructor that might fail; and (b) destructors can't fail. Weak. Is there a good counterargument? To be precise: why is the OP wrong to say that, to be strict about error handling, his C++ needs to look like the block of code that follows the sentence, "There's a new 'semi-terminated' state" in the article? (As for most of the comments, which boil down to "OP is ignorant of basic things about C++ and programming", come on you guys, how likely is that? Who's more likely displaying ignorance here?)
- pestaa 14y agoAuthor went from constructors+exceptions to init_foobar()+return value for error handling. When you misuse exceptions, they become unmanagable nightmare, which I believe would have happened with 0MQ. And throwing exceptions in constructors is one really good way to misuse them. And ranting about it seems like ignorance to me, but that's beside the point. For me, checking return values is just as, if not more, tedious than catching some exceptions. Return values should be used to guide the flow of the program state (IMHO), and exceptions represent invalid states.
- gruseom 14y agoYou still haven't responded to his point, which is that to deal with the reality that constructors and destructors can fail, he ended up having to write more complex code than he would in C. (Specifically, the code in the passage I cited, which turns each object into a little state machine.) Saying "just make those things not fail" is no answer at all. So, to repeat: how could he meet his error-handling goals in C++ without handling object construction/destruction in that state machine style? I have no opinion about this, but given that it's the point of the article, that's what people should be addressing.
- 14y ago
- ynniv 14y agoAs with most experiments in writing object oriented code in C, this looks a lot like Objective-C.
- cpeterso 14y agoC++ exception specifications are worse than nothing. Unlike Java's (controversial) checked exceptions, C++ exception specifications are not compile-time checked. Instead, the compiler generates run-time checks when calling function functions with exception specifications. If the function throws an exception that does match its specification, the program calls abort()!
- JohnnyContra 14y agoBjarne did it all for us. http://harmful.cat-v.org/software/c++/I_did_it_for_you_all http://harmful.cat-v.org/software/c++/I_did_it_for_you_all
- no_more_death 14y agoA spoiler: http://www.snopes.com/computer/program/stroustrup.asp http://www.snopes.com/computer/program/stroustrup.asp
- signa11 14y ago>Now consider what happens when you add inheritance to the mix. C++ allows to initialise base classes as a part of >derived class' constructor. Throwing an exception will destruct the parts of the object that were already successfully initialized with this which object is he talking about here ? if foo inherits from bar, object foo is not considered a valid object till it's constructor completes. so there is no question of destroying parts of objects which were already constructed. similarly, during object destruction, as soon as the destructor is invoked, the object is in an invalid state. i guess there are some issues in understanding of object lifetimes and exceptions thrown by it's constructors...
- malkia 14y agoJust to quickly note here: Certain very popular game console does not allow use of C++ exceptions - the underlying runtime / abi / whatever simply does not support it. Not that you would ship ZeroMQ code in it (it's GPL), but still. Oh, and I love ZeroMQ, and I even love it more, that the "C" interface was the one being public, not the "C++". Also good article. I love exceptions in higher-level languages - lisp, lua, etc. - but I prefer error codes in lower-level ones, and I consider C++ as such.
- jacquesm 14y agoThe one advantage of C over C++ is simple: what you see is what you get. If you have to wonder about what a statement really might mean depending on a bunch of state that was fed to the compiler then that really spoils things.
- 12uu45dd 14y agoOh well. It was probably faster and easier to code in C++ initially. And allowed him to beat all the competition to market.
- zvrba 14y agoHis reasoning is bogus. For his C equivalent, he writes: > There are only two states. Not initialised object/memory where all the bets are off and the structure can contain random data. He can get exactly the same effect by mimicking fstream interface: use constructors and destructors as they were meant to and introduce bool operator! to check whether the object has been successfully initialized. In this scenario, only destructor needs to know about the "fail-constructed" state. Other methods don't need to implement the state-machine; calling them on "fail-constructed" object would be undefined, exactly as in his C version (e.g., calling foo_bar without calling foo_init and checking that it succeeded)!
- anacrolix 14y agoI've always claimed that C++ exceptions are just awful. C++ gives exceptions a really bad name, and many never move onto, or back to another language that does it well. I've had excellent experience with exception handling in Python and Haskell. In particular in Python, exceptions contain fully debuggable stack and traceback information, and a complete set of statements to work with exceptions properly. try/else/except/finally. The exception hierarchy is also much better defined. C++ lacks a finally clause, and other niceties, and forces its half baked OO model onto you if you want to use exceptions "properly". That said, exceptions are one of those language features that just begs to be misused. I agree with Martin in that the fact that C lacks many of these dangerous constructs is one of its greatest appeals. He, I, and many others would prefer they just weren't available because they are inevitably deployed by some colleague or other. The (poor) use of C++ shows in zeromq, I've always found it highly volatile, and its interoperability suffers. Cryptic error messages the result of unhandled exceptions abound in my testing of it.