What's the effect of `std::istreambuf_iterator<char>(0)`?

27 views
Skip to first unread message

S.B.

unread,
Oct 1, 2015, 7:38:48 AM10/1/15
to ISO C++ Standard - Discussion
I think the constructor that gets called is `istreambuf_iterator::istreambuf_iterator(basic_streambuf<charT,traits>*)` and the result is an end-of-stream iterator. But looking at the specification of the aforementioned constructor, I found that the behavior of it when the argument is 0 (or a null pointer) seems to be artfully avoided.

Here is the specification (N4527 §24.6.3.2 [istreambuf.iterator.cons]p2)
istreambuf_iterator(basic_istream<charT,traits>& s) noexcept;
istreambuf_iterator(basic_streambuf<charT,traits>* s) noexcept;
2 Effects: Constructs an istreambuf_iterator<> that uses the basic_streambuf<> object *(s.rdbuf()),
or *s, respectively. Constructs an end-of-stream iterator if s.rdbuf() is null.

Nicol Bolas

unread,
Oct 1, 2015, 10:15:04 AM10/1/15
to ISO C++ Standard - Discussion

The behavior is right there. It uses `*s`. For any pointer expression `s`, the result of `*s` is only defined if `s` points to a valid object of that type. And nullptr never points to a valid object of any type.

So if `s` is nullptr, and the effects of this function are to store `*s`, then the program becomes undefined.

No need to say anything more than the obvious.

David Krauss

unread,
Oct 1, 2015, 11:46:18 AM10/1/15
to std-dis...@isocpp.org
Well, in practice, istreambuf_iterator is assignable, so it can’t have a member reference. It’s more likely to have a member pointer, which would also naturally fit the possibility of being singular.

So it’s pretty much inconceivable that the constructor would actually dereference the pointer parameter, and indeed both libc++ and libstdc++ simply copy its value to a member. So, it’s quite conceivable that this deserves a brief LWG defect report, sent to lwgchair at gmail dot com.

Daniel Krügler

unread,
Oct 1, 2015, 1:03:04 PM10/1/15
to std-dis...@isocpp.org
Agreed. Let me point out that according to [istreambuf.iterator] p1:

"The default constructor istreambuf_iterator() and the constructor
istreambuf_iterator(0) both construct an end-of-stream iterator object
suitable for use as an end-of-range."

Given the exposed constructors this indicates that

istreambuf_iterator(basic_streambuf<charT,traits>* s) noexcept;

is well-defined, but I believe that the wording in
[istreambuf.iterator.cons] should be improved to make that
crystal-clear.

The issue

http://cplusplus.github.io/LWG/lwg-active.html#2366

doesn't cover the question of interest here, therefore please submit a new one.

- Daniel
Reply all
Reply to author
Forward
0 new messages