This is the mail archive of the mailing list for the libstdc++ project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: throwing on codecvt_base::error

Sep 22, 2010 12:58:33 AM, wrote:

>On Sep 21, 2010, at 7:42 PM, Paolo Carlini wrote:
>> About 9182-1, what I *do* remember is that we noticed with Petur (and
>> Nathan) a number of circumstances where really we couldn't provide 
>> enough diagnostics to the user by way simply of return values from the
>> concerned functions. In general I think this is recognized as a real
>> issue in the current design of C++ iostreams. While I apply locally your
>> patch and tweak the linker map, most likely reporting back that I'm
>> going to commit your patch, you are welcome to start looking into the
>> issue in more detail and suggest possible changes...
>All good to hear!
>Right, there's only one error code for failure. However, basic_filebuf also 
>uses only one exception class, namely ios_base::failure. Having users test the what() 
>string isn't a good solution. (An alternative is implementation-specific subclasses.)
>The standard is very ambiguous about the exception specifications. overflow 
>is the only function to mention exceptions in the Returns clause, but underflow 
>and uflow are also mentioned in footnote 275 (attached to showmanyc). Furthermore, 
>underflow has no defined return value for an invalid pending sequence, only for 
>a "null" sequence. All such text is the basic_streambuf spec, not basic_filebuf, 
>so it's not so specific. The text and footnote suggest that showmanyc should 
>detect whether uflow and underflow will throw, which sounds to me like detecting 
>e.g. whether a file is open or not. There is no way to pre-detect conversion failure, 
>which makes this particular kind of throw more dangerous.
>On the other hand, the user is allowed to throw from do_out and do_in. However, 
>they might not want that to happen in all contexts. On the other however, there 
>aren't many uses for codecvt outside basic_filebuf, being so esoteric and intrinsically 
>There is another solution, which is to define certain values of state_type to 
>represent errors. (For example, set the high-order bit of a scalar state_type.) 
>Then, the user can retrieve it via a very simple change to _M_seek:
>-	      __ret.state(_M_state_cur);
>	    }
>	}
>+      __ret.state(_M_state_cur);
>     return __ret;
>If sync incurs a codecvt error, seekoff(0,ios::cur) will as well. Does putting 
>it in state() violate the requirement to return pos_type(off_type(-1))? Hmm, maybe 
>it's OK. possibly says that state is significant when comparing fpos 
>values, but the GNU implementation (bits/postypes.h) ignores it. It depends whether 
>"equivalence relation" is interpreted per se, or in the context of other 
>One thing we certainly can improve is, requirement 2: overflow 
>is not allowed to consume characters that weren't output. Preserving the put 
>area also preserves the cause of the error and the ability to recover from it. For 
>if ( ! my_stream.flush() ) { // flush also optionally throws an ios::failure
>   // Something went wrong; attempt to correct error.
>   // This requires a custom streambuf, and tapping into (redefined) _M_state_last.
>   if ( my_stream.rdbuf()->my_check_put_area_for_error() ) {
>       throw my_io_exception( "invalid input: ", my_stream.rdbuf()->my_get_put_area() 
>   } else { // put area is OK, must be I/O error
>       rejigger_file();
>       if ( ! my_stream.flush() ) { // retry
>           throw my_io_exception( "unwritten data: ", my_stream.rdbuf()->my_get_put_area() 
>       }
>   }
>Preserving the put area also allows for extending the optimized case of xsputn.
>Well, that looks like enough discussion for one day. I've also coded up 
>and tested the elimination of _M_reading and _M_writing, but that's less exciting.
>	- Cheers,
>	D

This is a side note to your discussion but we need to put it on the list:

In C++0X ios_base::failure has an ABI breaking change of inheritance hierarchy from exception to system_error.  This will allow one to pass more system-specific information.  I had started something on this.  I got bungled trying to support both C++-0X and C++-98 IIRC.  I'll try to dig up my patch.

Obviously it doesn't help C++-98 but it's worth putting on the radar.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]