scope(exit)

Sean Kelly sean at f4.ca
Mon May 15 04:26:33 PDT 2006


MM wrote:
>> Personally, I find the basic guarantee to be of very limited use.  For 
>> most operations, the weak guarantee seems far more appropriate, and I 
>> believe it is reasonable to expect that of the lock function.  In other 
>> words, if the lock function fails then I would expect m to be in the 
>> state it was in prior to the lock call.  Further, it's possible that 
>> unlock might consider being asked to unlock a mutex that the calling 
>> thread doesn't own to be an error condition, which may result in an 
>> exception being generated.  Therefore, if lock fails and throws and 
>> exception and scope(exit) unlock(m) therefore fails and throws an 
>> exception as well, the application will terminate because it has two 
>> exceptions in flight simultaneously.  Therefore:
>>
>>     lock(m);
>>     scope(exit) unlock(m);
>>
>> is preferred because unlock will only be called if a lock was 
>> successfully obtained, and will be called regardless of whether the 
>> following code generates an error or completes successfully.
> 
> Lock && unlock could ofcourse be any arbitrary function.. thus I was asking
> myself, why use the weak guarantee? When you take the change on a fault in lock
> at about the same as unlock your reasoning would be sound. But most of the
> time(in my code:) the 'unlock' function is far less complex than the 'lock'
> function.
> Is it then still better to use the weak guarantee?(not a retoric question... :)

Typically, you want to use the strongest guarantee you can reasonably 
provide, which in most cases is the weak guarantee.  The strong 
guarantee is mostly reserved for dtors and other operations that simply 
cannot fail, and it is typically either too difficult or is simply 
inadvisable to provide for anything but clean-up or certain other 
critical operations.  The weak guarantee is what most people expect: if 
an error occurs, it's as if they had never called the function.  By 
contrast, the basic guarantee merely ensures that a failure won't leave 
your application inclined to light its hair on fire and jump out a 
window--data structures are allowed to remain partially modified so long 
as they are in a stable state, etc.

As for the scope declarations, it makes sense to me that they should 
occur after whatever operation they are paired with.  That is, if a 
function fails then I would expect that to mean it hadn't done whatever 
it was supposed to do and there should be no need to call the paired 
function.  So if lock/open/whatever throws an exception then it was 
unable to lock/open/do whatever it was supposed to do.  If for some 
reason this function is a complex multi-step process that can't be 
recovered from if something goes wrong and exceptions simply must be 
thrown at arbitrary locations then consider redesigning the component :-)


Sean



More information about the Digitalmars-d mailing list