On 29/09/15 10:50 -0600, Martin Sebor wrote: >On 09/29/2015 10:15 AM, Jakub Jelinek wrote: >>On Tue, Sep 29, 2015 at 05:10:20PM +0100, Jonathan Wakely wrote: >>>>That looks wrong to me, you only restore errno if you don't throw :(. >>>>If you throw, then errno might remain 0, which is IMHO undesirable. >>> >>>My thinking was that a failed conversion that throws an exception >>>should be allowed to modify errno, and that the second case sets it to >>>ERANGE sometimes anyway. >> >>Well, you can modify errno, you just shouldn't change it from non-zero to >>zero as far as the user is concerned. >> >>http://pubs.opengroup.org/onlinepubs/009695399/functions/errno.html >>"No function in this volume of IEEE Std 1003.1-2001 shall set errno to 0." >>Of course, this part of STL is not POSIX, still, as you said, it would be >>nice to guarantee the same. > >FWIW, I agree. It's a helpful property. If libstdc++ provides >the POSIC/C guarantee it would be nice to document it in the >manual. > >That said, this part of the C++ spec (stoi and related) is specified >to such a level of detail that one might argue that the functions >aren't allowed to reset errno in an observable way. Yes, looking at the spec again it's not as simple as my original patch or as simple as always restoring the previous value. We are required to call one of the strtoX functions from the C library, and if that sets errno C++ says nothing about resetting it, see http://eel.is/c++draft/string.conversions So we need to zero it to reliably detect ERANGE being set, but we should undo that if it doesn't get set (i.e. is still zero). But if the strtoX function sets errno to anything non-zero then it looks as though that should be left unchanged. So the scope-guard type should do: ~_Restore_errno() { if (errno == 0) errno = _M_errno; } I noticed that we're also zeroing errno in the generic c_locale.cc file so we need something similar there. >As an aside, I objected to this specification when it was first >proposed, not because of the errno guarantee, but because the >functions were meant to be light-weight, efficient, and certainly >thread-safe means of converting strings to numbers. Specifying >their effects as opposed to their postconditions means that can't >be implemented independent of strtol and the C locale, which makes >them anything but light-weight, and prone to data races in >programs that call setlocale. Agreed, but that's not a cause I want to fight for :-)