public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: "François Dumont" <frs.dumont@gmail.com>
Cc: libstdc++@gcc.gnu.org, gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] libstdc++: istreambuf_iterator proxy (was: keep attached streambuf)
Date: Tue, 10 Oct 2017 14:21:00 -0000	[thread overview]
Message-ID: <20171010142147.GD3090@redhat.com> (raw)
In-Reply-To: <41ed5a91-9b23-97a4-ab38-4728091279d7@gmail.com>

On 06/10/17 18:01 +0200, François Dumont wrote:
>On 03/10/2017 22:39, Petr Ovtchenkov wrote:
>>On Thu, 28 Sep 2017 13:38:06 +0100
>>Jonathan Wakely<jwakely@redhat.com>  wrote:
>>
>>>On 28/09/17 15:06 +0300, Petr Ovtchenkov wrote:
>>>>On Thu, 28 Sep 2017 11:34:25 +0100
>>>>Jonathan Wakely<jwakely@redhat.com>  wrote:
>>>>>>+  VERIFY(i == std::istreambuf_iterator<char>());
>>>>>>+
>>>>>>+  VERIFY(memcmp(b, r, 36) == 0);
>>>>>>+
>>>>>>+  s << q;
>>>>>>+  VERIFY(!s.fail());
>>>>>>+
>>>>>>+  copy_n(i, 36, r);
>>>>>This is undefined behaviour. The end-of-stream iterator value cannot
>>>>>be dereferenced.
>>>>Within this test istreambuf_iterator in eof state never dereferenced.
>>>That is quite implementation dependent.
>>>
>>>The libc++ and VC++ implementations fail this test, because once an
>>>istreambuf_iterator has been detected to reach end-of-stream it
>>>doesn't get "reset" by changes to the streambuf.
>>If we will keep even "unspecified" behaviour same, then bug fix/drawback
>>removing become extremely hard: it should be identified as drawback
>>in all libs almost simultaneously.
>>
>>>The libc++ implementation crashes, because operator== on an
>>>end-of-stream iterator sets its streambuf* to null, and any further
>>>increment or dereference will segfault.
>>>
>>>So this is testing something that other implementations don't support,
>>>and isn't justifiable from the standard.
>>I will use N4687 as reference.
>>
>>27.2.3 par.2 Table 95:
>>
>>++r
>>
>>Requires: r is dereferenceable. Postconditions: r is dereferenceable or r is
>>past-the-end; any copies of the previous value of r are no longer required
>>either to be dereferenceable or to be in the domain of ==.
>>
>>(void)r++ equivalent to (void)++r
>>
>>*r++
>>
>>{ T tmp = *r;
>>++r;
>>return tmp; }
>>
>>[BTW, you see that r++ without dereference has no sense, and even more,
>>
>>   copies of the previous
>>   value of r are no longer
>>   required either to be
>>   dereferenceable or to be in
>>   the domain of ==.
>>
>>From this follow, that postfix increment operator shouldn't return
>>istreambuf_iterator.
>>]
>>
>>>>The test itself simulate "stop and go" istream usage.
>>>>stringstream is convenient for behaviuor illustration, but in "real life"
>>>>I can assume socket or tty on this place.
>>>At the very minimum we should have a comment in the test explaining
>>>how it relies on non-standard, non-portable behaviour.
>>>
>>>But I'd prefer to avoid introducing more divergence from other
>>>implementations.
>>Standard itself say nothting about "stop and go" scenario.
>>At least I don't see any words pro or contra.
>>But current implementation block usage of istreambuf_iterator
>>with underlying streams like socket or tty, so istreambuf_iterator become
>>almost useless structure for practice.
>Why not creating a new istreambuf_iterator each time you need to check 
>that streambuf is not in eof anymore ?
>
>>We have three issues with istreambuf_iterator:
>>   - debug-dependent behaviour
>Fixed.
>>   - EOL of istreambuf_iterator when it reach EOF (but this not mean
>>     EOL of associated streambuf)
>Controversial.
>>   - postfix increment operator return istreambuf_iterator, but here
>>     expected restricted type, that accept only dereference, if it possible.
>I agree that we need to fix this last point too.
>
>Consider this code:
>
>  std::istringstream inf("abc");
>  std::istreambuf_iterator<char> j(inf), eof;
>  std::istreambuf_iterator<char> i = j++;
>
>  assert( *i == 'a' );
>
>At this point it looks like i is pointing to 'a' but then when you do:
>
>std::string str(i, eof);
>
>you have:
>assert( str == "ac" );
>
>We jump other the 'b'.

Right, but this code isn't required to work. These are Input
Iterators. The fact that incrementing j affects other copies of the
iterator is expected.


>We could improve the situation by adding a debug assertion that _M_c 
>is eof when pre-increment is being used

Hmm, interesting idea.

>or by changing semantic of 
>pre-increment to only call sbumpc if _M_c is eof. But then we would 
>need to consider _M_c in find overload and in some other places in the 
>lib I think.
>
>Rather than going through this complicated path I agree with Petr that 
>we need to simply implement the solution advised by the Standard with 
>the nested proxy type.
>
>This is what I have done in the attached patch in a naive way. Do we 
>need to have abi compatibility here ? If so I'll rework it.
>
>This patch will make libstdc++ pass the llvm test. I even duplicate it 
>on our side with a small refinement to check for the return value of 
>the proxy::operator*().

I agree with the earlier analysis that the libc++ test is not required
to work (i've reported this to the libc++ maintainers and expect them
to move it to their nonportable test directory).  So we don't need to
change our implementation to make it pass.


  parent reply	other threads:[~2017-10-10 14:21 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-23  7:10 [PATCH] libstdc++: istreambuf_iterator keep attached streambuf Petr Ovtchenkov
2017-09-25 13:46 ` Jonathan Wakely
2017-09-28 10:34 ` Jonathan Wakely
2017-09-28 12:06   ` Petr Ovtchenkov
2017-09-28 12:38     ` Jonathan Wakely
2017-10-03 20:39       ` Petr Ovtchenkov
2017-10-04  5:04         ` [PATCH v2] " Petr Ovtchenkov
2017-10-06 16:01         ` [PATCH] libstdc++: istreambuf_iterator proxy (was: keep attached streambuf) François Dumont
2017-10-06 18:00           ` Petr Ovtchenkov
2017-10-08 14:59             ` [PATCH] libstdc++: istreambuf_iterator proxy François Dumont
2017-10-09 19:32               ` Petr Ovtchenkov
2017-10-10  5:52               ` Petr Ovtchenkov
2017-10-10 14:21           ` Jonathan Wakely [this message]
  -- strict thread matches above, loose matches on Subject: below --
2017-10-13 17:14 Make istreambuf_iterator::_M_sbuf immutable and add debug checks François Dumont
2017-10-23 19:08 ` François Dumont
2017-11-06 21:19   ` François Dumont
2017-11-16  5:52     ` Petr Ovtchenkov
2017-11-16 10:57       ` Jonathan Wakely
2017-11-16 11:46         ` Jonathan Wakely
2017-11-16 12:08           ` Petr Ovtchenkov
2017-11-16 17:40           ` François Dumont
2017-11-16 18:12             ` Petr Ovtchenkov
2017-11-16 21:31               ` François Dumont
2017-09-27 20:16 Make tests less istreambuf_iterator implementation dependent François Dumont
2017-09-28 12:12 ` Jonathan Wakely
2017-09-28 19:59   ` François Dumont
2017-09-28 21:56     ` Jonathan Wakely
2017-10-02  5:43       ` François Dumont
2017-10-03 14:20         ` Jonathan Wakely
2017-10-04 16:21           ` François Dumont
2017-10-04 23:23             ` Jonathan Wakely
2017-11-15 20:52             ` [PATCH 1/4] Revert "2017-10-04 Petr Ovtchenkov <ptr@void-ptr.info>" Petr Ovtchenkov
2017-11-15 20:52               ` [PATCH 2/4] libstdc++: istreambuf_iterator keep attached streambuf Petr Ovtchenkov
2017-11-15 20:52                 ` [PATCH 3/4] libstdc++: avoid character accumulation in istreambuf_iterator Petr Ovtchenkov
2017-11-15 20:52                   ` [PATCH 4/4] libstdc++: immutable _M_sbuf " Petr Ovtchenkov
2017-11-15 21:31                   ` [PATCH 3/4] libstdc++: avoid character accumulation " Paolo Carlini
2017-11-16  5:32                     ` Petr Ovtchenkov
2017-11-16  9:39                       ` Paolo Carlini
2017-11-16 11:03                         ` Petr Ovtchenkov
2017-11-16 11:29                           ` Paolo Carlini
2017-11-16 11:41                             ` Petr Ovtchenkov
2017-11-16 11:51                               ` Paolo Carlini
2017-11-16 10:56               ` [PATCH 1/4] Revert "2017-10-04 Petr Ovtchenkov <ptr@void-ptr.info>" Jonathan Wakely
2017-11-16 11:35                 ` Petr Ovtchenkov
2017-11-16 11:39                   ` Jonathan Wakely
2017-11-16 11:40                     ` Jonathan Wakely
2017-11-16 11:57                     ` Petr Ovtchenkov
2017-08-24 11:27 [PATCH] streambuf_iterator: avoid debug-dependent behaviour Petr Ovtchenkov
2017-08-29 20:02 ` François Dumont
2017-08-30  5:05   ` Petr Ovtchenkov
2017-08-31 20:30     ` François Dumont
2017-09-01  9:10 ` Jonathan Wakely
2017-09-07 21:02   ` François Dumont
2017-09-08  5:47     ` Petr Ovtchenkov
2017-09-08  6:15       ` François Dumont
2017-09-09 20:17       ` François Dumont
2017-09-21  5:46         ` François Dumont
2017-09-28 10:50           ` Jonathan Wakely
2017-09-28 10:58             ` Jonathan Wakely
2017-09-21 18:23   ` Petr Ovtchenkov
2017-09-25  9:34     ` Petr Ovtchenkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171010142147.GD3090@redhat.com \
    --to=jwakely@redhat.com \
    --cc=frs.dumont@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).