Can C++ streambuf methods throw exceptions?

2019-06-22 08:58发布

问题:

I'm trying to find a method to get the number of characters read or written to a stream that is reliable even if there is an error and the read/write ends short.

I was doing something like this:

return stream.rdbuf()->sputn(buffer, buffer_size);

but if the streambuf implementation of overflow is permitted to throw excpections this won't work. Is it? I've not been able to find it documented anywhere.

回答1:

basic_streambuf::overflow is allowed to throw an exception upon failure as documented in 27.6.3.4.5/6, and sadly there's no way to ensure compile-time that the function won't ever throw an exception.

Seems like you are running out of luck and the only way to be 100% sure that overflow won't throw an exception is to write your own streambuf that just doesn't do that upon failure.


[27.6.3.4.5/2-3] int_type overflow(int_type = c = traits::eof ())
...

[27.6.3.4.5/5]

Requires: Every overriding definition of this virtual function shall obey the following constraints:

1) The effect of consuming a character on the associated output sequence is specified309

2) Let r be the number of characters in the pending sequence not consumed. If r is non-zero then pbase() and pptr() shall be set so that: pptr() - pbase() == r and the r characters starting at pbase() are the associated output stream. In case r is zero (all characters of the pending sequence have been consumed) then either pbase() is set to NULL, or pbase() and pptr() are both set to the same NULL non-value.

3) The function may fail if either appending some character to the associated output stream fails or if it is unable to establish pbase() and pptr() according to the above rules.

[27.6.3.4.5/6]

Returns: traits::eof () or throws an exception if the function fails