Prev: Is there any standard/guarantees for exception safety in STL operations?
Next: compiling error "conversion from ‘int’ to non-scalar type"
From: Francis Glassborow on 19 Jul 2010 23:07 Thomas Richter wrote: > > ??? 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? You are exaggerating. The STL guarantees exception safety. What it does not do is to guarantee the strong version under all circumstances. For example suppose that you try to insert a block of ten elements into a container and that an exception is thrown during this process. You will still have a stable container in a destructable state. However the Standard does not guarantee that it is in the same state that it was prior to your attempt to insert elements. That seems very reasonable to me. Maybe inserting the first 7 elements was successful and it only failed on the eighth, unpicking the process would be costly, indeed preparing for such a failure would be costly which is why it is left to the programmer to provide that extra if they need it. The most obvious way to do that is to create a (temporary) copy of the original container but that is clearly expensive in both time and resources. Do you know of a a way to avoid cost and yet provide a strong guarantee for multiple insertions? If not what magic do you think WG21 has that you do not? > > 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. With respect, nonsense. AFAICS the Standard Library gives the strongest guarantees compatible with acceptable performance. 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? No optimism required, just an awareness of the different levels of exception safety and choosing the one appropriate to your work. As always more safety will generally require more work. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: nmm1 on 20 Jul 2010 04:05 In article <ldSdnd8LPeCX_9jRnZ2dnUVZ8hKdnZ2d(a)bt.com>, Francis Glassborow <francis.glassborow(a)btinternet.com> wrote: >Thomas Richter wrote: > >> 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. > >With respect, nonsense. AFAICS the Standard Library gives the strongest >guarantees compatible with acceptable performance. With respect, that is complete nonsense. Firstly, we could argue about what constitutes 'acceptable performance', which has changed over the past 20 years, anyway, due to technological changes. But let's skip that unproductive debate. Secondly, it is not true even for the STL, let alone for the whole of the standard library. There is a lot more that could be said, both with regard to static checking and with regard to reliable exception handling. From my experience as an implementor of such things, FAR more can be specified and done, PORTABLY, than most people realise. The problem with this is that specifying implementable and usable exception handling is not easy, and nor is implementing it. My normal rule is that it needs at least as much effort as dealing with the non-exception cases. But that is DESIGN effort, and not a loss of run-time performance. 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 20 Jul 2010 09:47 Francis Glassborow wrote: >> ??? 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? > > You are exaggerating. The STL guarantees exception safety. What it does > not do is to guarantee the strong version under all circumstances. Certainly I am, and it was certainly provocative (but for a reason); I understand that the STL doesn't provide such a strong guarantee, but while I understand some of the reasoning behind, I somehow see that in conflict with the principles of the language. I'll come to that later on. > For example suppose that you try to insert a block of ten elements into > a container and that an exception is thrown during this process. You > will still have a stable container in a destructable state. However the > Standard does not guarantee that it is in the same state that it was > prior to your attempt to insert elements. Certainly, that is understood. But assume that the copy constructors of my classes cannot throw (otherwise, of course, I agree that all bets are off, and my code is to blame, and not the STL). However, even then the STL does not ensure that the container is in a state where either all new elements are present, or it remained in the original state. I can certainly arrange that (insert, swap), but without knowing the implementation of insert, not in a way that is as efficient as it could. Clearly, such an implementation would be slower (needless to say), but still required to write code that provides a "useful" guarantee in case of exceptions. Or to make it more concrete: Assume that I can ensure you that my copy constructor doesn't throw, *how* should I deal with exceptions I get from insert()? Basically, I cannot handle them since I do not know what the state of the object is after insertion (except that it is to some degree valid, syntactically at least, but not semantically). Thus, what should I do then - really as a practical advice? Realistically, I can only terminate, or scan the object fully to find what is inserted and what is not. Or I must build a copy/swap around it. Neither solution is attractive, though knowing the STL implementation, finding such "stale elements" might be simpler or even trivial. > That seems very reasonable to me. Maybe inserting the first 7 elements > was successful and it only failed on the eighth, unpicking the process > would be costly, indeed preparing for such a failure would be costly > which is why it is left to the programmer to provide that extra if they > need it. The most obvious way to do that is to create a (temporary) copy > of the original container but that is clearly expensive in both time and > resources. Yes, true, but maybe - knowing some internals of the implementation - I could do that in a better way, for some containers at least? Thus, for example, I could add all elements one after another into a temporary object which is then atomically added to the container in a last step? Look, what I'm saying is that I don't understand the "sloppy" approach of the STL with respect to exceptions, giving me only very limited means how to handle them. Another way to address this would be if the STL would give means at hand to "cleanup" a partially affected object - I don't mind if the exception case is expensive, i.e. I could also think of an implementation where inserted objects are marked as temporaries, to be removed in an exception, etc, etc. > Do you know of a a way to avoid cost and yet provide a strong guarantee > for multiple insertions? If not what magic do you think WG21 has that > you do not? I'm not talking about "magic". I'm talking about giving me more means how to address exceptions in case they happen. As a third implementation strategy, I might also be able to deal with insert() in such a way that I know that of M elements in case of an exception only the first N, N >= 0, N <= M are inserted, so I could remove them. But the STL doesn't even say that. Could also be the last N. Or instead of that provide me any information on how I could restore the object - provide me with a function that tells whether the first N or the last N objects have been inserted. Anything like that would be, IMHO, required to continue program execution in a *known* state. But the STL doesn't leave me with a *known* program state, so how should I continue if I don't know what happened? This is my central point: I do not know, and the STL gives me no means, to get my program back to a known state. It leaves so much freedom to the implementation that I either need a *completely* different stategy (copy, insert, swap), must implement myself knowing *my* strategy, or abort the program. >> 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. > > With respect, nonsense. AFAICS the Standard Library gives the strongest > guarantees compatible with acceptable performance. Now you're provocative - but that's ok, it's my fault to begin with. Anyhow, I afraid it isn't quite as nonsensical as you seem. It's ok to say that I cannot expect to have either all or no elements inserted. But it should give me better means to restore an object into such a state in case the exception happened. For example, by providing information which elements have been inserted and which not, or by requiring documentation on that by the implementation or... I don't see this as a black&white issue by enforcing the strong guarantee, which I probably don't need. But what I do need is a known program state to recover from, and an STL that helps me by doing that. >> 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? > > No optimism required, just an awareness of the different levels of > exception safety and choosing the one appropriate to your work. As > always more safety will generally require more work. Obviously, but not quite the point. When looking at STL guarantees, I do have the feeling that little thought has been put into how to handle exceptional cases, but those are the cases that let my programs crash in worst case, so I - as a program author - should better know how to deal with them. I see that in conflict with the C++ design where I should better know what I'm doing, and I should be extremely careful with exceptions. With as little information as I get, I only have very limited strategies in handling such cases, whereas my programming praxis tells me that I usually need more. Terminating a program is the last resort, and as said, I don't need exceptions for that. So long, Thomas -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Francis Glassborow on 21 Jul 2010 08:25 Thomas Richter wrote: >> >> No optimism required, just an awareness of the different levels of >> exception safety and choosing the one appropriate to your work. As >> always more safety will generally require more work. > > Obviously, but not quite the point. When looking at STL guarantees, I do > have the feeling that little thought has been put into how to handle > exceptional cases, but those are the cases that let my programs crash in > worst case, so I - as a program author - should better know how to deal > with them. I see that in conflict with the C++ design where I should > better know what I'm doing, and I should be extremely careful with > exceptions. With as little information as I get, I only have very > limited strategies in handling such cases, whereas my programming praxis > tells me that I usually need more. Terminating a program is the last > resort, and as said, I don't need exceptions for that. > > So long, Remember that the STL is just a library without any special support from the core of the language. So it can only do what any intelligent programmer can do for themselves. Now despite a very large amount of thought and discussion among Library experts (WG21 and elsewhere) no-one has produced (AFAIK) an enhanced STL with stronger guarantees. That does not prove that it is impossible to do so, but given the desirability for as much exception safety as possible it does suggest that it requires methods that are yet to be discovered/invented. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Louis Lavery on 21 Jul 2010 08:26
On 21/07/2010 01:47, Thomas Richter wrote: > Francis Glassborow wrote: > >>> ??? 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? >> >> You are exaggerating. The STL guarantees exception safety. What it >> does not do is to guarantee the strong version under all circumstances. > > Certainly I am, and it was certainly provocative (but for a reason); I > understand that the STL doesn't provide such a strong guarantee, but > while I understand some of the reasoning behind, I somehow see that in > conflict with the principles of the language. I'll come to that later on. > >> For example suppose that you try to insert a block of ten elements >> into a container and that an exception is thrown during this process. >> You will still have a stable container in a destructable state. >> However the Standard does not guarantee that it is in the same state >> that it was prior to your attempt to insert elements. > > Certainly, that is understood. But assume that the copy constructors of > my classes cannot throw (otherwise, of course, I agree that all bets are > off, and my code is to blame, and not the STL). However, even then the > STL does not ensure that the container is in a state where either all > new elements are present, or it remained in the original state. I can > certainly arrange that (insert, swap), but without knowing the > implementation of insert, not in a way that is as efficient as it could. I think there are quite efficient ways to do multiple inserts such that the container is in a known state should it throw (E.g. a combination of splice and range constructors for lists and capacity and reserve for vectors). Maybe not as efficiently as the lib's multiple insert, but then that's optimised and so doesn't cater for recovery after a throw. Exception safety does cost, you know. It does, of course, require some thought. Louis. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |