8 ms·
Why RAII rocks
- dicroce 12y agoDoes your language have mutexes and exceptions? You NEED RAII...
- st3fan 12y agoWelcome to 2015.
- KeytarHero 12y agoYes, of course RAII is much shorter than a contrived example designed to be as long as possible. Here's a much shorter version: int unsafe2() { A* a = new A; int retval = 0; if (a->f()) { B* b = new B; if (b->f()) retval = b->g(); else retval = a->g(); delete b; } delete a; return retval; } I agree that RAII is a good thing, but can we please avoid straw-man examples?
- WizzleKake 12y agoWhy not just put a and b on the stack then? ;) Bjarne says, "Code that creates an object using new and then deletes it at the end of the same scope is ugly, error-prone, and inefficient."
- KeytarHero 12y agoBecause it's an example of allocating things on the heap. You could also say the same about the "good" RAII version shown - but then there wouldn't be much point to the article, would there?
- lumpypua 12y agoHow does this version handle exceptions?
- KeytarHero 12y agoIt doesn't. Just like the example it replaces. I'm not saying this is the best way to write this code - there are several reasons RAII is better. But in this case, "look how messy non-RAII code is!" isn't the reason.
- st3fan 12y agoThe original example does actually properly deal with exceptions.
- Devid2014 12y agoThis code work with assertion that constructors of A and B will never throw !
- Devid2014 12y agoDo you want to tell that this is correct and bug free code ? This is a example how to create lot of Memory Leaks.
- KeytarHero 12y agoIt's certainly not bug free. But that's not the point. All I did was rewrite that example with half as much code. The point of that example seems to be "look how much less code RAII takes!" and I'm just trying to show that, although you should use RAII, that's not the reason why.
- deleted 12y ago[deleted]
- fiveoak 12y agoWon't this leak A if B's constructor throws an exception?
- jasode 12y agoI think 3 responses here have misinterpreted what you're illustrating. (e.g. "won't that leak?!?!") KeytarHero could have wrote: "Here's a much shorter more realistic version of new/delete code that will have problems such as leakage after exceptions" Since he didn't make that explicit, 3 replies seem to have misinterpreted the post as: "Here's a much shorter version that won't leak and doesn't need RAII" Basically, his example is supposed to be "wrong" but it's a shorter version of "wrong".
- KeytarHero 12y agoExactly. Thanks.
- kuon 12y agoIsn't that similar to ARC in Objective-C?
- mcphage 12y agoARC is (almost) purely automatic. You write your code however, and then a code analyzer goes through it to figure out where to put the memory management calls. (Also I'm pretty sure ARC still just does reference counting).
- Joky 12y agoARC stands for Automatic Reference Counting: http://en.wikipedia.org/wiki/Automatic_Reference_Counting http://en.wikipedia.org/wiki/Automatic_Reference_Counting
- pixelglow 12y agoEssentially, yes. In ARC, all strong pointers may have multiple owners. In C++11 RAII, the typical, defining use is for single owners (std::unique_ptr) but multiple owners are supported too (std::shared_ptr). In ARC, local pointers may be reclaimed before their scope ends, if the compiler determines no further use of the pointer. In C++11 RAII, all such resources are reclaimed only at scope end. ARC is not exception-safe by default, you have to compile with -fobjc-arc-exceptions to make it exception safe; however Apple standards have been moving away from using exceptions for recoverable conditions for some time now. C++11 RAII is of course exception-safe by default, it's one of the rationales behind the technique.
- zwieback 12y agoI was surprised how little I missed manual memory management when I switched from C++ to C# for everyday work. RAII is something I do miss, though, even after years of C# I still feel lifetime management of objects is awkward.
- tonyedgecombe 12y agoFor unmanaged resources using provides almost the same thing, the only downside I can see is it means yet more nesting.
- cbsmith 12y agoThe other downside is you aren't as cleanly encapsulating the resource management logic.
- MaulingMonkey 12y agoYou can forget to write a using statement. In C++ you can omit your destructor entirely if all the members are already RAII classes, whereas in C# you still need to write a .Dispose() method. Memory management is by and far the vast majority of resource management in C++ for me, which C# takes care of with garbage collection - so I don't miss RAII too much in C#. But if you tried to give me a C++ with using blocks but no RAII (read: you gave me C) I'd scream. RAII is no panacea[1] - I'd say C#'s manual resource burden without RAII is still less than C++'s with RAII. Which is why I don't miss it too much. But it'd still be a nice addition. And I missed it dearly during my initial adoption of C#. [1] e.g. in C++, you still have to worry about reference cycles, implementing the RAII constructs in the first place if existing ones aren't suitable, ensuring parents are kept in scope while referencing children, etc..
- vodik 12y ago> But if you tried to give me a C++ with using blocks but no RAII (read: you gave me C) If you don't care about MSVC, IMHO new C code should be using the gcc cleanup extension: http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization#GCC_.22cleanup.22_extension_for_C http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial...
- okasaki 12y agoWhy would you heap allocate something that you're deleting in the same function? Isn't there some equivalent length example that isn't so contrived?
- EpicEng 12y agoThere are numerous cases when one would do exactly that, which all boil down to "this thing is too big for stack allocation." Ever done any image processing?
- bmm6o 12y agoEven in cases like that it's uncommon for the object to actually take up a lot of stack space. Since member variable's sizes have to be known at compile time it only applies to fixed-size (or parametrized) buffers.
- vodik 12y agoAs far as I know, using `new` or not has nothing to really do if it goes onto the stack or not. That's simply a common implementation details. What its really saying is if the lifetime is automatic or manual. Maybe I'm confusing C with C++ or just outright confused, but to my understanding, nothing says that: int foo[] = <massive amount of data>; actually has to live on the stack.
- EpicEng 12y agoWell, in practice, it's both. Sure, stacks and heaps are an implementation detail, but they're pervasive. You simply can't write int x[10000][10000]; and expect it to not cause a stack overflow in any real world implementation. It's an implementation detail you absolutely need to be aware of.
- bmm6o 12y ago> nothing says that [...] actually has to live on the stack. This might be possible in theory but I've never seen it in practice.
- santaclaus 12y agoLove me some RAII. Also, why is C++ chock full of such opaque acronyms? RAII and SFINAE come to mind.
- wololongong 12y agoMore: NRVO, Pimpl, SBRM, EBO, NVI, ODR, CRTP, STL, RTTI, TMP. I've been using C++ for the past year at work. It's an absolute nightmare to learn.
- jjuhl 12y agoA year? That's nothing. Personally I'd consider anyone with less than 5 years of professional C++ experience a newbie. It's a complex language, it takes years to learn it well.
- stinos 12y agoSBRM, EBO, NVI, ODR, TMP -> care to explain those? Anyway it does prove your point: have been using c++ way longer than you and these don't immediately ring a bell. Always more to learn! (or at least, always more super subtle details you'll only encounter once in a lifetime)
- electricCoder 12y agoSBRM = Scope Bound Resource Management ( another name for RAII ) EBO = Empty Base Optimization NVI = Non-Virtual Interface ODR = One Definition Rule TMP = Template Meta Programming
- stinos 12y agoFunny. I do know all those principles but had no idea there were common abbreviations.
- EliRivers 12y agoIt's old, and it was created and sharpened by old people with Unix smudges on their fingers. This is not so much a good answer, as an excuse to indulge myself and listen to Stephenson for a moment. The file systems of Unix machines all have the same general structure. On your flimsy operating systems, you can create directories (folders) and give them names like Frodo or My Stuff and put them pretty much anywhere you like. But under Unix the highest level--the root--of the filesystem is always designated with the single character "/" and it always contains the same set of top-level directories: /usr /etc /var /bin /proc /boot /home /root /sbin /dev /lib /tmp and each of these directories typically has its own distinct structure of subdirectories. Note the obsessive use of abbreviations and avoidance of capital letters; this is a system invented by people to whom repetitive stress disorder is what black lung is to miners. Long names get worn down to three-letter nubbins, like stones smoothed by a river.
- alexnewman 12y agoRust is the answer. C++ is just soo legacy.
- jjuhl 12y agoSo what? Sure, rust is the new thing, node.js is the new thing, forget about SQL since NoSQL is the current thing. Etc etc, Bla bla bla. I hate this "let's chase every new thing and everything old is shit" attitude. C++ may be old but it does a great job at what it is targeted for (just like Fortran and many other "old" things). I'd really wish more people would stop chasing "new shiney" and just get work done. C++ may be complicated and old, but it gets work done. Old, complicated and legacy does not equal bad.
- nightski 12y agoIt's also caused billions of dollars in damage. Hell, even just null pointers. Saying it does a great job is very generous. Even if it is the best language for low level work, it is still barely acceptable. We should strive for advancement and progress in our field. There is a large difference between this and chasing the latest fad JS framework. Unless you are saying that programming is a solved problem and C++ is about as advanced as we'll ever get.
- falcolas 12y agoAnd Rust is still going through its shakedown cruise. I wouldn't yet be comfortable taking it in the deep waters where C++ currently roams. There's still a lot of need for tooling, testing, and letting people with smaller projects (and/or non-Mozilla use cases) shake out the bugs. Give it a few successful years post 1.0, and Rust will be in a better place to truly take the mantle from C++.
- nightski 12y agoAgreed! I do not even use Rust myself (yet). I just do not think the comparison to the NoSQL/JS Frameworks craze is valid. There are real fundamental improvements being tried in Rust, hopefully it turns out for the better.