[Exception] Why is there no non-const version of get_error_info?

get_error_info takes a const exception object and returns a pointer to const data object of respective error_info. But why is there no way of getting non-const pointer (which would allow to modify the data)? This is especially strange because operator << can be used to add data to a const exception object so I don't see reason for not being able to get modifiable data back (at least from non-const exception object). Having this would allow me to safely gather exception data before throwing or during exception propagation. What I wanted was to insert an empty vector of data to the preconstructed exception object. Then obtain the vector with get_error_info (since operator << adds a copy I have to get the actual object). Then call reserve on the obtained vector and start the actual operation. During the operation I can gather (possible) error data and safely add it to the vector since memory is already reserved. In the end if any error data was gathered I will throw the preconstructed exception object. In reasonable implementation this should be safe as well. (Similar thing might be done while propagating the exception.) With current code (lack of non-const get_error_info) it is not possible. I have to get the vector from exception object. Then add data to the vector (this may fail). Then again add vector to the exception object (overwriting old vector; this may fail). And in the end throw (if needed). Alternatively I could preconstruct vector, reserve space add data to it. Then in the end if I will throw the data vector is there for me. However I still have to add it to the exception object and this still may fail. Adam Badura

On Wed, Aug 19, 2009 at 5:14 AM, Adam Badura<abadura@o2.pl> wrote:
get_error_info takes a const exception object and returns a pointer to const data object of respective error_info. But why is there no way of getting non-const pointer (which would allow to modify the data)?
The easy answer is: because I haven't needed to modify the data, and nobody has requested it before. Logically, the error info interface is intended for recording various known facts about an exception object: "What's the name of the file that failed to open?" "What error code did the OS report?" Etc. etc. These things aren't mutable.
This is especially strange because operator << can be used to add data to a const exception object so I don't see reason for not being able to get modifiable data back (at least from non-const exception object).
Adding error info is supported for const exceptions because it isn't stored in the exception object itself, it's stored in a separate object the exception points to. This arrangement can't be just an implementation detail because the copy constructor is required to be nothrow. The other reason is to support the throw foo() << my_Info() syntax.
Having this would allow me to safely gather exception data before throwing or during exception propagation. What I wanted was to insert an empty vector of data to the preconstructed exception object. Then obtain the vector with get_error_info (since operator << adds a copy I have to get the actual object). Then call reserve on the obtained vector and start the actual operation. During the operation I can gather (possible) error data and safely add it to the vector since memory is already reserved. In the end if any error data was gathered I will throw the preconstructed exception object. In reasonable implementation this should be safe as well. (Similar thing might be done while propagating the exception.)
I'm curious, could you post more information about your use case? What's this vector, what kind of objects/info does it store? I'm not against your request, but I want to understand your motivation better. (Also note that a failure to add error info to an exception is not the end of the world, the system is exception-safe.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

AMDG Emil Dotchevski wrote:
On Wed, Aug 19, 2009 at 5:14 AM, Adam Badura<abadura@o2.pl> wrote:
This is especially strange because operator << can be used to add data to a const exception object so I don't see reason for not being able to get modifiable data back (at least from non-const exception object).
Adding error info is supported for const exceptions because it isn't stored in the exception object itself, it's stored in a separate object the exception points to. This arrangement can't be just an implementation detail because the copy constructor is required to be nothrow.
The other reason is to support the throw foo() << my_Info() syntax.
If operator<< is defined as a member function then it can take an rvalue exception and still be non-const. In Christ, Steven Watanabe

On Wed, Aug 19, 2009 at 3:49 PM, Steven Watanabe<watanabesj@gmail.com> wrote:
AMDG
Emil Dotchevski wrote:
On Wed, Aug 19, 2009 at 5:14 AM, Adam Badura<abadura@o2.pl> wrote:
This is especially strange because operator << can be used to add data to a const exception object so I don't see reason for not being able to get modifiable data back (at least from non-const exception object).
Adding error info is supported for const exceptions because it isn't stored in the exception object itself, it's stored in a separate object the exception points to. This arrangement can't be just an implementation detail because the copy constructor is required to be nothrow.
The other reason is to support the throw foo() << my_Info() syntax.
If operator<< is defined as a member function then it can take an rvalue exception and still be non-const.
Oh wow, I did not know that. Thanks for the information! Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Wed, Aug 19, 2009 at 3:49 PM, Steven Watanabe<watanabesj@gmail.com> wrote:
AMDG
Emil Dotchevski wrote:
On Wed, Aug 19, 2009 at 5:14 AM, Adam Badura<abadura@o2.pl> wrote:
This is especially strange because operator << can be used to add data to a const exception object so I don't see reason for not being able to get modifiable data back (at least from non-const exception object).
Adding error info is supported for const exceptions because it isn't stored in the exception object itself, it's stored in a separate object the exception points to. This arrangement can't be just an implementation detail because the copy constructor is required to be nothrow.
The other reason is to support the throw foo() << my_Info() syntax.
If operator<< is defined as a member function then it can take an rvalue exception and still be non-const.
Oh, bummer. We can't do this in boost::exception because it is critical for the exception type (the "this" if op<< were a member) to be deduced implicitly. More precisely, the return type of op<< has to be the same as the type of the object on the left of op<<, so we don't get a slice in an expression like throw foo()<<my_info(). Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

I'm curious, could you post more information about your use case? What's this vector, what kind of objects/info does it store? I'm not against your request, but I want to understand your motivation better.
In our system we use Observer pattern through Observable and Listener classes. Now Observable in its core function "notify" iterates through all registered Listeners and calls their "onNotify" function. This is quite simple. However it gets complicated once we start to take exceptions into account. (Generally Listener's onNotify should not throw. This is motivated with two reasons: 1) it should be simple and fast, 2) object which caused the notification most likely cannot handle the exception anyway. Or at least such are popular guidelines for implementing Observer pattern. However in my opinion this is inconvenient [especially if one wants to be correct according to Standard and must in result take into account that almost any standard function may throw almost anything]. It is hard to write and maintain such "onNotifys" and I'm afraid that it might be in general not possible at all. So we do take into account exceptions thrown from "onNotify".) Now consider a case where there are 3 Listeners. "notify" executes. First Listener has its "onNotify" called and does just fine. But second one throws. There is no way to somehow revert the "onNotify" already executed on the first Listener. So if we just propagate the exception we will end in incorrect state since first Listener was already notified, second is in state dependent on the exception and third was not notified at all. My idea was to catch any exceptions thrown from "onNotifys", store them in the vector and then rethrow a different exception (for now called MultiException) which would contain that vector as its data. This makes it much harder to catch the exception since now to catch exception X you will have to catch exception X and MultiException to see if it contains X. On the other hand exceptions from "notify" will not usually be handled anyway and the exception data serves only diagnostic purposes. So I do not consider it a major issue. My first design was to do code like: typedef boost::error_info< SubExceptionsInfoTag, std::vector< boost::exeption_ptr > > SubExceptionsInfo; // Does not throw. MultiException exceptionObject; // May throw. We haven't started notifying yet so no problem. exceptionObject << SubExceptionsInfo( std::vector< boost::exeption_ptr
() ); // Does not throw. // THIS IS NOT POSSIBLE BECAUSE CURRENTLY THE RETURNED POINTER IS CONST. std::vector< boost::exception_ptr >* pExceptionsVector = boost::get_error_info< SubExceptionsInfo >( exceptionObject ); // Prepare memory for worst case: every Listener throws. // May throw. We haven't started notifying yet so no problem. pExceptionsVector->reserve( m_listenersList.size() );
// We are ready with exceptionObject. Start actual notifications. for each listener in listenersList { try { call onNotify on the listener } catch ( ... ) { // Store the exception and continue the loop. // current_exception does not throw. // push_back will not throw since: // 1) memory is already reserved, // 2) boost::exeption_ptr copy constructor does not throw. pExceptionsVector->push_back( boost::current_exception() ); } } // If any exception was thrown then throw exceptionObject. if ( !pExceptionsVector->empty() ) // exceptionObject copy constructor does not throw. throw exceptionObject; With get_error_info returning a const pointer this no longer is possible. The closes approach would be to just have a simple vector with pre-reserved memory and then after the loop we will construct MultiException add that vector to it and throw it. However this may fail twice: adding vector to the exception and copying the vector. If this fails then a new exception will be thrown and original exception data will be lost. And I think it is bad because it can be quite easily written so that it either fails before notifying or fails only with onNotify exceptions. Adam Badura

From your description, it seems the first thing you need to consider is what is the exception safety guarantees of the function that notifies the listeners, as a whole.
1) If only basic exception safety guarantee is required, then you simply don't worry about the exceptions: if a onNotify throws, it'll propagate the exception out. 2) If strong exception safety guarantee is required, then you must make sure that if a onNotify throws, the effects of the already completed onNotifys can be undone without an error. Then, you propagate the exception as in 1). 3) Nothrow exception safety guarantee: you know onNotify won't throw. It seems you're leaning towards 3). If that's the case, if an onNotify throws, you have a bug. Therefore I don't think it is a good idea at all to "keep going". If I were you, I'd just catch(...) and assert(), possibly after logging boost::current_exception_diagnostic_information() somewhere. That said, if you want to attach a bunch of exception_ptrs to a boost::exception, you could just use different tags: typedef boost:error_info<struct onNotifyFoo_,boost::exception_ptr> onNotifyFoo; typedef boost:error_info<struct onNotifyBar_,boost::exception_ptr> onNotifyBar; Alternatively, you can collect them all into a std::vector<boost::exception_ptr>. When you're done calling onNotifys, if the vector is not empty you just throw an exception, adding the vector to it. If you are concerned about the (remote?) possibility of a std::bad_alloc propagating instead of your exceptions, you shouldn't be because that could happen anyway. To throw an exceptoin, the runtime needs memory to store the exception object. In some implementations that memory comes from the heap, so an attempt to throw any exception whatsoever could result in a std::bad_alloc instead (the runtime is required to have enough memory to throw a std::bad_alloc.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode On Wed, Aug 19, 2009 at 11:03 PM, Adam Badura<abadura@o2.pl> wrote:
I'm curious, could you post more information about your use case? What's this vector, what kind of objects/info does it store? I'm not against your request, but I want to understand your motivation better.
In our system we use Observer pattern through Observable and Listener classes. Now Observable in its core function "notify" iterates through all registered Listeners and calls their "onNotify" function. This is quite simple. However it gets complicated once we start to take exceptions into account. (Generally Listener's onNotify should not throw. This is motivated with two reasons: 1) it should be simple and fast, 2) object which caused the notification most likely cannot handle the exception anyway. Or at least such are popular guidelines for implementing Observer pattern. However in my opinion this is inconvenient [especially if one wants to be correct according to Standard and must in result take into account that almost any standard function may throw almost anything]. It is hard to write and maintain such "onNotifys" and I'm afraid that it might be in general not possible at all. So we do take into account exceptions thrown from "onNotify".) Now consider a case where there are 3 Listeners. "notify" executes. First Listener has its "onNotify" called and does just fine. But second one throws. There is no way to somehow revert the "onNotify" already executed on the first Listener. So if we just propagate the exception we will end in incorrect state since first Listener was already notified, second is in state dependent on the exception and third was not notified at all. My idea was to catch any exceptions thrown from "onNotifys", store them in the vector and then rethrow a different exception (for now called MultiException) which would contain that vector as its data. This makes it much harder to catch the exception since now to catch exception X you will have to catch exception X and MultiException to see if it contains X. On the other hand exceptions from "notify" will not usually be handled anyway and the exception data serves only diagnostic purposes. So I do not consider it a major issue. My first design was to do code like:
typedef boost::error_info< SubExceptionsInfoTag, std::vector< boost::exeption_ptr > > SubExceptionsInfo;
// Does not throw. MultiException exceptionObject; // May throw. We haven't started notifying yet so no problem. exceptionObject << SubExceptionsInfo( std::vector< boost::exeption_ptr >() ); // Does not throw. // THIS IS NOT POSSIBLE BECAUSE CURRENTLY THE RETURNED POINTER IS CONST. std::vector< boost::exception_ptr >* pExceptionsVector = boost::get_error_info< SubExceptionsInfo >( exceptionObject ); // Prepare memory for worst case: every Listener throws. // May throw. We haven't started notifying yet so no problem. pExceptionsVector->reserve( m_listenersList.size() );
// We are ready with exceptionObject. Start actual notifications.
for each listener in listenersList { try { call onNotify on the listener } catch ( ... ) { // Store the exception and continue the loop.
// current_exception does not throw. // push_back will not throw since: // 1) memory is already reserved, // 2) boost::exeption_ptr copy constructor does not throw. pExceptionsVector->push_back( boost::current_exception() ); } }
// If any exception was thrown then throw exceptionObject. if ( !pExceptionsVector->empty() ) // exceptionObject copy constructor does not throw. throw exceptionObject;
With get_error_info returning a const pointer this no longer is possible. The closes approach would be to just have a simple vector with pre-reserved memory and then after the loop we will construct MultiException add that vector to it and throw it. However this may fail twice: adding vector to the exception and copying the vector. If this fails then a new exception will be thrown and original exception data will be lost. And I think it is bad because it can be quite easily written so that it either fails before notifying or fails only with onNotify exceptions.
Adam Badura
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Taking into account our previous discussions I expected that you will rather try to convince me that what I was going to do is bad rather then try to add non-const get_error_info. :)
From your description, it seems the first thing you need to consider is what is the exception safety guarantees of the function that notifies the listeners, as a whole.
1) If only basic exception safety guarantee is required, then you simply don't worry about the exceptions: if a onNotify throws, it'll propagate the exception out.
2) If strong exception safety guarantee is required, then you must make sure that if a onNotify throws, the effects of the already completed onNotifys can be undone without an error. Then, you propagate the exception as in 1).
3) Nothrow exception safety guarantee: you know onNotify won't throw.
It seems you're leaning towards 3). If that's the case, if an onNotify throws, you have a bug. Therefore I don't think it is a good idea at all to "keep going". If I were you, I'd just catch(...) and assert(), possibly after logging boost::current_exception_diagnostic_information() somewhere.
I thought about it a lot. :) And in this case it is not so simple. I would prefer 3) however I don't thing that reasonable system can be done assuming 3) (without large risk of exception data loss - since I consider premature excepting logging as exception data loss). So 3) is not acceptable (especially taking into consideration that standard gives almost no guarantees on exception throwing so virtually anything non-trivial might possibly throw). 2) would be great to. However is not possible as well. Mainly because there are operations which might fail during reverting which defeats this idea. So 1) is left and this is what I have now. But I would like something better. I would like to notify all listeners even if they any of them fails. Because this is what observable is supposed to do - notify listeners. If I allow it to skip further onNotify calls once an exception is thrown I am in a state which is almost surely unrecoverable because even if I deal somehow with the error I have no way of continuing notifications from the interrupt place. I could add such feature but it would be rather complex.
That said, if you want to attach a bunch of exception_ptrs to a boost::exception, you could just use different tags:
typedef boost:error_info<struct onNotifyFoo_,boost::exception_ptr> onNotifyFoo; typedef boost:error_info<struct onNotifyBar_,boost::exception_ptr> onNotifyBar;
This obviously will not do since number of listeners is known at runtime.
Alternatively, you can collect them all into a std::vector<boost::exception_ptr>. When you're done calling onNotifys, if the vector is not empty you just throw an exception, adding the vector to it.
If you are concerned about the (remote?) possibility of a std::bad_alloc propagating instead of your exceptions, you shouldn't be because that could happen anyway. To throw an exceptoin, the runtime needs memory to store the exception object. In some implementations that memory comes from the heap, so an attempt to throw any exception whatsoever could result in a std::bad_alloc instead (the runtime is required to have enough memory to throw a std::bad_alloc.)
Yes. I described that method as an alternative. And yes I am concerned with risk of std::bad_alloc. And yes I cannot avoid it fully anyway. But Boost exceptions objects are small so the risk is marginal. And if this happens anyway then I consider it an error so fatal that I will not recover from it anyway - just unwind the stack. Just because you cannot avoid accident does not meant that you will put yourself to an unnecessary risk, right? Want another example? What about stack trace? I could have a sequence container in the exception and in each catch in which I will rethrow the exception I would add source code location data to have better diagnostic information. Obviously I cannot do this with fixed number of separate error_infos (without loss of data). And again I could each time get the stack trace, add new entry and reset the stack trace with new collection. But with the same problems as previously. Unnecessary risk of failure and decreased execution speed. But I will not only defend myself but rather strike back now! :) (Keep in mind it is a joke!) What are the reasons to not have non-const get_error_info? I haven't look into implementation but I guess it requires almost no work at all to add (and maintain) it. I don't see also design purpose. If you allow to not only modify once created exception object but also modify a const exception object (I agree it is useful and convenient and I wouldn't like it being removed) then you should allow to modify data in that object. I don't see reason to treat the data in special way. Especially that after all I can overwrite it with different value so in fact achieve the same but in less efficient and safe method. Adam Badura

On Thu, Aug 20, 2009 at 2:59 PM, Adam Badura<abadura@o2.pl> wrote:
Taking into account our previous discussions I expected that you will rather try to convince me that what I was going to do is bad rather then try to add non-const get_error_info. :)
The reputation I got, Jesus. :)
Alternatively, you can collect them all into a std::vector<boost::exception_ptr>. When you're done calling onNotifys, if the vector is not empty you just throw an exception, adding the vector to it.
If you are concerned about the (remote?) possibility of a std::bad_alloc propagating instead of your exceptions, you shouldn't be because that could happen anyway. To throw an exceptoin, the runtime needs memory to store the exception object. In some implementations that memory comes from the heap, so an attempt to throw any exception whatsoever could result in a std::bad_alloc instead (the runtime is required to have enough memory to throw a std::bad_alloc.)
Yes. I described that method as an alternative. And yes I am concerned with risk of std::bad_alloc. And yes I cannot avoid it fully anyway. But Boost exceptions objects are small so the risk is marginal. And if this happens anyway then I consider it an error so fatal that I will not recover from it anyway - just unwind the stack. Just because you cannot avoid accident does not meant that you will put yourself to an unnecessary risk, right?
Are you sure the reserve() will reduce the risk significantly? Note that boost::exception_ptr itself also allocates memory, not to mention the onNotify functions themselves, assuming they aren't trivial they could be allocating things as well.
Want another example? What about stack trace? I could have a sequence container in the exception and in each catch in which I will rethrow the exception I would add source code location data to have better diagnostic information. Obviously I cannot do this with fixed number of separate error_infos (without loss of data).
Yes that's a good one though the stack trace should be captured in one go before you throw. The trouble is this isn't possible in a platform-independent way; I'm hoping someone will come up with platform-specific implementation. I will add this support as soon as it's available, I do believe it is a very valuable diagnostic tool.
But I will not only defend myself but rather strike back now! :) (Keep in mind it is a joke!) What are the reasons to not have non-const get_error_info? I haven't look into implementation but I guess it requires almost no work at all to add (and maintain) it.
In fact yesterday I went ahead and implemented it on my system, seems fine. I'll do some more testing and I'll commit it to trunk soon. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Are you sure the reserve() will reduce the risk significantly? Note that boost::exception_ptr itself also allocates memory, not to mention the onNotify functions themselves, assuming they aren't trivial they could be allocating things as well.
If onNotify throws due to lack of memory then it is just as if it threw anything else. (Except for slightly larger risk of failure in throwing MultiException due to lack of memory for the exception itself.) boost::current_exception and boost::exception_ptr operations do are declared to not throw. I was surprised that boost::current_exception does not throw even std::bad_alloc but documentation says that. So in case of lack of memory it returns exception_ptr to std::bad_alloc. Not ideal however still my main purpose was to continue notifying and then rethrow all the exceptions again with as small risk (of another failure) as possible.
Yes that's a good one though the stack trace should be captured in one go before you throw. The trouble is this isn't possible in a platform-independent way; I'm hoping someone will come up with platform-specific implementation. I will add this support as soon as it's available, I do believe it is a very valuable diagnostic tool.
Yes. It would be better to get the stack trace before throwing. However for now (and I guess for long) it is not possible. While adding stack trace in catch blocks during unwinding is. As it comes to stack trace I have thought a lot about it but anything I imagined required adding special code to the functions which are to be stack-traced (so likely every). I guess this could come down to a single auxiliary function call wrapped in a macro however still it is not a good solution. And off-topic here. :)
In fact yesterday I went ahead and implemented it on my system, seems fine. I'll do some more testing and I'll commit it to trunk soon.
Nice surprise. Thanks. Adam Badura

On Thu, Aug 20, 2009 at 10:29 PM, Adam Badura<abadura@o2.pl> wrote:
Are you sure the reserve() will reduce the risk significantly? Note that boost::exception_ptr itself also allocates memory, not to mention the onNotify functions themselves, assuming they aren't trivial they could be allocating things as well.
If onNotify throws due to lack of memory then it is just as if it threw anything else. (Except for slightly larger risk of failure in throwing MultiException due to lack of memory for the exception itself.)
std::string get_file_name(); throw foo() << boost::errinfo_file_name(get_file_name()); All I was saying is that if op<< throws std::bad_alloc, this is the same as getting std::bad_alloc from the get_file_name() function or from the std::string copy constructor, or even from the runtime if it runs out of memory trying to throw (the already successfully initialized with error infos and all) foo. You shouldn't worry about this stuff, just collect your exception_ptrs in a std::vector then add it to the exception at the point of the throw. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
Logically, the error info interface is intended for recording various known facts about an exception object: "What's the name of the file that failed to open?" "What error code did the OS report?" Etc. etc. These things aren't mutable.
What about a program that translates some complicated requests into other kinds of requests, then executes them using the same code that handles the simple requests usually? (This is similar to translating complex CPU instructions into a sequence of simpler ones in a scheduler, then using the same execution units that the simple instructions use, just that this would be in software instead of hardware.) If one of the simple instructions throws an exception and records exception information, this simplification must be undone at some point to not leak the implementation detail of the simplification step. I can't think of a concrete case for this right now, but modifying exception information certainly seems like a reasonable thing to do (if it can be implemented without too much difficulty). (Sorry if my explanation wasn't terribly clear.) --Jeffrey Bosboom

See trunk revision 55707. Thanks for the suggestion. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode On Wed, Aug 19, 2009 at 5:14 AM, Adam Badura<abadura@o2.pl> wrote:
get_error_info takes a const exception object and returns a pointer to const data object of respective error_info. But why is there no way of getting non-const pointer (which would allow to modify the data)?
This is especially strange because operator << can be used to add data to a const exception object so I don't see reason for not being able to get modifiable data back (at least from non-const exception object).
Having this would allow me to safely gather exception data before throwing or during exception propagation. What I wanted was to insert an empty vector of data to the preconstructed exception object. Then obtain the vector with get_error_info (since operator << adds a copy I have to get the actual object). Then call reserve on the obtained vector and start the actual operation. During the operation I can gather (possible) error data and safely add it to the vector since memory is already reserved. In the end if any error data was gathered I will throw the preconstructed exception object. In reasonable implementation this should be safe as well. (Similar thing might be done while propagating the exception.)
With current code (lack of non-const get_error_info) it is not possible. I have to get the vector from exception object. Then add data to the vector (this may fail). Then again add vector to the exception object (overwriting old vector; this may fail). And in the end throw (if needed). Alternatively I could preconstruct vector, reserve space add data to it. Then in the end if I will throw the data vector is there for me. However I still have to add it to the exception object and this still may fail.
Adam Badura
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

See trunk revision 55707. Thanks for the suggestion.
Fine. But why this version requires non-const exception object? Usually you catch exception like "catch ( const T& e )" so it will not work. And it seems strange because to add data you may have a const object. Will it be available in 1.40? Adam Badura

AMDG Adam Badura wrote:
See trunk revision 55707. Thanks for the suggestion.
Fine. But why this version requires non-const exception object? Usually you catch exception like "catch ( const T& e )" so it will not work.
Then catch by non-const reference. In Christ, Steven Watanabe

On Sat, Aug 22, 2009 at 2:37 AM, Adam Badura<abadura@o2.pl> wrote:
See trunk revision 55707. Thanks for the suggestion.
Fine. But why this version requires non-const exception object? Usually you catch exception like "catch ( const T& e )" so it will not work. And it seems strange because to add data you may have a const object.
I can't think of any reason to catch a T const & instead of T &.
Will it be available in 1.40?
No, 1.40 is pretty much spoken for. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
participants (4)
-
Adam Badura
-
Emil Dotchevski
-
Jeffrey Bosboom
-
Steven Watanabe