Incorrect implementation of codecvt<char, char, mbstate_t> in codecvt.cc

Bo Persson bop@gmb.dk
Sat Jan 12 23:48:00 GMT 2008


Oops - the first reply went away before I had added my comments...


Kristian Spangsege wrote:

> On 1/12/08, Bo Persson <bop at gmb dot dk> wrote:
>> Kristian Spangsege wrote:
>>
>>     The implementation of codecvt<char, char, mbstate_t> is not in
>>     agreement with DR19 (TC). It may be due to a misinterpretation
>>     of the text there, and if so, the problem could also be
>>     present in the implementation of codecvt<wchar_t, char,
>>     mbstate_t> - I haven't checked that.
>>
>>
>>
>>     '__from_next' is set equal to '__from'. According to DR19 it
>>     must instead be set equal to '__from_end' (the next argument
>>     after '__from'.)
>>
>>
>>
>>     From DR19:
>>
>>         If returns noconv, internT and externT are the same type
>>         and the converted sequence is identical to the input
>>         sequence [from,from_next). to_next is set equal to to, the
>>         value of state is unchanged, and there are no changes to
>>         the values in [to, to_limit).
>>
>>
>>
>>     The way I interpret this is as follows: If the return value is
>>     'noconv' then it indicates that the initial section
>>     [from,from_next) of the input can be used directly as output
>>     since the converted sequence would by identical had it been
>> computed.
>>
>>
>> Yes, but as there has been no conversion at all,
>
> It is true that no conversion has been done, but it is reasonable to
> say that your 'noconv' reply concerns the entire input, and as such
> the entire input has been accounted for, from the point of view of
> the facet user. In a sense the 'noconv' reply lets you process input
> without producing output. So...
>
>> what should the "end
>> of consumed input sequence" be?
>
> It should be 'from_end', since you wish to express that it is the
> entire input that requires no conversion. This line of thought will
> also allow you to restrict you 'noconv' reply to a prefix of the
> presented input. DR19 directly suggests such usage by saying:
>> ... and the
>> converted sequence is identical to the input sequence
>> [from,from_next).

But the default char-char conversion is degenerate in that never 
converts anything. This is signalled by the always_noconv() function 
returning true.

You shouldn't be surprised that do_in() and do_out() returns noconv. 
They always do!

>
> Back to you comments:
>
>> Setting __from_next = __from indicates
>> that no characters were used.
>
> Yes, indeed, but that is in conflict with my interpretation of DR19.
> Setting '__from_next = __from' is a non-statement saying that the
> _zero_ initial characters of input needs no conversion.

But the return value is 'noconv', meaning that there is no conversion. 
Otherwise the return value would have been 'partial' (or worse - a 
failure).

>
> I should mention that I'm not trying to persuadu you that the DR19
> directions are technically better than the decisions made in the GCC
> implementation. However I think it is important that GCC adhere to
> the DR TMs. Also, the comment in the code above indicates that in
> this case a consious decision was made to adhere to DR19.
>
> Had DR19 added the following line, the GCC implementation would have
> been both good (in my oppinion) and conformant:
>> If 'do_out' returns 'noconv' and '__from_next == __from' upon
>> return it means that the 'no conversion' result concerns the
>> entire input string.
> Alas, this is not want DR19 says :-)

I don't think there is a conflict. Honestly.


>>
>> I think your code will have to special case 'noconv' anyway, since
>> it
>> will have to output the from-sequence (all of it). Other cases will
>> have to output the to-sequence (possibly in a loop, handling
>> partial
>> conversions).
>
> I don't know exactly what you mena here. Could I ask you to
> elaborate a bit on those points?

The 'noconv' case differs in several ways. One is that the to-sequence 
is empty. After calling the 'conversion', you have to output the 
from-sequence instead. After doing that, it is not very hard to 
realize that the entire from-sequence is processed.

An alternative way is to call the always_noconv() function first and, 
if it returns true, just skip the calls to in() and out().


Bo Persson



More information about the Libstdc++ mailing list