Prev: Is there any standard/guarantees for exception safety in STL operations?
Next: why aren't comparators passed as refs or c-refs in algorithms?
From: Bo Persson on 19 Jul 2010 04:52 Michael Kilburn wrote: > On Jul 18, 3:29 pm, Daniel Kr�gler <daniel.krueg...(a)googlemail.com> > wrote: >>> I have checked C++ standard and did not find requirements imposed >>> on library implementation with respect to exception safety. >>> ... >> >> There exist some very general statements and guarantees, see below. > > Yes, I saw them... the problem is that quite often they are not > "very general" -- they are incomplete! I'll quote an example from > those provided by you: > > >> 5) 23.1/10: >> >> "Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all >> container types defined in this clause meet the following >> additional requirements: >> � if an exception is thrown by an insert() function while >> inserting a single element, that function has no effects. > > ... and what if we are inserting more than one element? what > effect(s) we are going to have? Bad probably. :-) You could also read this as a hint to not insert multiple obejcts at once, if they are likely to throw exceptions. As an application programmer, you might know that there are plenty of resources available so your classes will not throw right now. > > >> � no swap() function throws an exception unless that exception >> is thrown by the copy constructor or assignment operator of >> the container�s Compare object (if any; see 23.1.2).[..]" > > ... and what is going to happen to the object? The Compare object is provided by you, the programmer. This rule can be read as: "If you take care of the Compare object not throwing, the library guarantees the rest of the container." It is extremely unusual for compare objects to throw during a swap. Instead of outright forbidding it, the library instead warns you that throwing is not good. Perhaps you, as a programmer, can determine if this particular compare object for this particular container is likely to throw or not during the next swap. If it is safe, go ahead and swap the container. If not, perhaps you can avoid the swap? Or live with the consequences? Bo Persson -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Richter on 19 Jul 2010 13:43 Bo Persson wrote: >>> "Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all >>> container types defined in this clause meet the following >>> additional requirements: >>> � if an exception is thrown by an insert() function while >>> inserting a single element, that function has no effects. >> ... and what if we are inserting more than one element? what >> effect(s) we are going to have? > > Bad probably. :-) > > You could also read this as a hint to not insert multiple obejcts at > once, if they are likely to throw exceptions. This statement looks very irritating to me. What means "likely"? Is proper programming a matter of probability? > As an application programmer, you might know that there are plenty of > resources available so your classes will not throw right now. ??? How should I know how many resources are available? The lack of any strong guarantee more or less means that proper handling of resource exhaustion is impossible if you insert more than one element at once. IOW, all I can do then is to terminate the program? Now, for *that* I don't need exceptions, do I? Similar to the OP, I find it very irritating that at one hand education in C++ stresses proper exception handling and exception safety so much, while at the other hand the STL provides you with so little to really *write* exception safe code when using it. That is, code with *guaranteed* behavior in case of exceptions. Basically, doesn't that mean that one should stay away from the STL when writing code that can *truely* handle exceptions correctly, instead of just "hoping the best", i.e. an optimistic approach as you seem to suggest? So long, Thomas -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Bo Persson on 20 Jul 2010 04:09 Thomas Richter wrote: > Bo Persson wrote: > >>>> "Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all >>>> container types defined in this clause meet the following >>>> additional requirements: >>>> if an exception is thrown by an insert() function while >>>> inserting a single element, that function has no effects. >>> ... and what if we are inserting more than one element? what >>> effect(s) we are going to have? >> >> Bad probably. :-) >> >> You could also read this as a hint to not insert multiple obejcts >> at once, if they are likely to throw exceptions. > > This statement looks very irritating to me. What means "likely"? Is > proper programming a matter of probability? Yes, sometimes. :-) You, as the one writning the possibly throwing copy constructor of a class, could know when the exception might occur. The library author cannot. If you insert 10 small elements into a std::vector, and have 100 GB of virtual memory available, a std::bad_alloc is not "likely". You can ask yourself, under what conditions will an exception occur? Do we have these conditions right now? Can we run out of memory? Disk space? Network connections? File handles? > >> As an application programmer, you might know that there are plenty >> of resources available so your classes will not throw right now. > > ??? How should I know how many resources are available? It depends on what resorces the stored objects require. If you write the classes, you know that but the library author does not. > The lack of > any strong guarantee more or less means that proper handling of > resource exhaustion is impossible if you insert more than one > element at once. IOW, all I can do then is to terminate the > program? Now, for *that* I don't need exceptions, do I? One way to get the strong guarantee is to say that copy constructors and assignment cannot throw. But that limits the usefulness of the library. Another way to get a strong guarantee is to make a copy of the container, attempt the inserts and, if successful, swap it with the original. That would be costly, of course, and increase the risk of getting a bad_alloc. Still another way is to insert your objects one at a time. That either works, or not, leaving the contairner in a known state. > > Similar to the OP, I find it very irritating that at one hand > education in C++ stresses proper exception handling and exception > safety so much, while at the other hand the STL provides you with > so little to really *write* exception safe code when using it. That > is, code with > *guaranteed* behavior in case of exceptions. Basically, doesn't that > mean that one should stay away from the STL when writing code that > can *truely* handle exceptions correctly, instead of just "hoping > the best", i.e. an optimistic approach as you seem to suggest? > The library provides you with a lot of tools, but it just cannot help you with everything for free. If you have a class that throws exceptions randomly, that isn't very useful. Bo Persson -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: nmm1 on 26 Jul 2010 02:47 In article <113846b1-5d14-4f3e-8f55-b5f5b9a96fa8(a)5g2000yqz.googlegroups.com>, Howard Hinnant <howard.hinnant(a)gmail.com> wrote: >> >> >Many people don't realize that it is relatively easy to add features >> >when using a minimal & fast library - making an informed engineering >> >tradeoff between features and performance. But when given a feature- >> >rich library (without access to a low-level API), one can't make it >> >fast when you don't need the features. Doing so is a common mistake >> >in library design: forgetting or dismissing the importance of the low- >> >level layer. >> >> That is extremely true, but is in flat contradiction to what the >> OP asked for, and what I understood Dragan Milenkovic to mean. >> >> The same is true for RAS, only even more so, and yet more for actual >> recovery. It is a common and catastrophic mistake to think that >> either are features, because they are not, and cannot be built on >> top of a design that doesn't have them. They are fundamental >> properties of the base design and implementation. >> >> There is NO WAY that a programmer can add recovery facilities to >> the current STL. An implementor can - but, to make it usable, has >> to specify its properties and constraints - i.e. design an extended >> STL standard. > >After reading your post I got the feeling that I had overlooked a >proposed design for an extended STL standard in this thread. So I >reread the thread but somehow am still missing it. I look forward to >reading a detailed proposal for an extended STL standard. Please don't be silly. If you had reread the thread, you should have noticed a posting of mine where I stated that extending the STL to support recovery from exceptions would be at least as much design, specification and implementation effort as has been put into the existing one. As I said, I have practical experience with similar tasks, and I know what is involved! If people want to work on such a thing, I am very happy to help (and even draft proposals as to how), but it is not something that can be done in one person's spare time. I am not convinced that it is a good idea, starting from here, anyway - though I don't know C++ well enough to be sure of that - to a great extent, it depends a lot on how much of the liberty inherited from C is sacrificable (just as for garbage collection, only more so). As an example of what can be specified, consider a container. It is possible to specify that insertions, deletions etc. are either nullified or completed, even when interrupted by exceptions caused by asynchronous signals. That is tricky to implement efficiently, so another approach is that any container where an operation is interrupted in some way must be sanitised by calling a special method before being used again, and then the same applies. And, similarly, interrupted sorting never loses or duplicates elements, or adds junk. All of that is known technology, but is in no sense a trivial extension. It is even possible to specify that containers are robust against a limited amount of data corruption - that starts getting extremely hairy, so I doubt that anyone would want to go there! But it could be done. Regards, Nick Maclaren. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Richter on 26 Jul 2010 07:18
nmm1(a)cam.ac.uk wrote: > > As an example of what can be specified, consider a container. It is > possible to specify that insertions, deletions etc. are either > nullified or completed, even when interrupted by exceptions caused > by asynchronous signals. That is tricky to implement efficiently, > so another approach is that any container where an operation is > interrupted in some way must be sanitised by calling a special > method before being used again, and then the same applies. And, > similarly, interrupted sorting never loses or duplicates elements, > or adds junk. All of that is known technology, but is in no sense > a trivial extension. Let's stick to this example, because it is an excellent one. I don't think asking for the strong guarantee, i.e. that insertions or deletions are either done completely or not at all. This is probably asking for too much. But what I'm asking for is exactly what you mention below, namely either a method to sanitize the container, or at least *some* information *how* to sanitize it. Consider for example an implementation that ensures that on insertion, the first N of a total of M elements make it into the container; by that I mean that after an exception, there is an N such that the elements 1,2,.. to N have been inserted and are now members of the container, and all I would need to do would be to remove them again. Thus, I would need to find out N after an exception, and the guarantee that insertions always happens in element increasing order from the source. Is this asking for too much? As far as I know, the STL doesn't even give me that. > It is even possible to specify that containers are robust against > a limited amount of data corruption - that starts getting extremely > hairy, so I doubt that anyone would want to go there! But it could > be done. Maybe - it would probably require completely different design principles, and the costs might be high, but I don't really know. Something simpler would be sufficient. So long, Thomas -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |