Topic: floating issue/idea: istream >> x "fail" case


Author: anthonypon@gmail.com
Date: Wed, 25 Feb 2015 20:29:37 -0800 (PST)
Raw View
------=_Part_1847_652735975.1424924977559
Content-Type: multipart/alternative;
 boundary="----=_Part_1848_1187062949.1424924977560"

------=_Part_1848_1187062949.1424924977560
Content-Type: text/plain; charset=UTF-8

Hello,

This is a "*Float the idea" *post per the
https://isocpp.org/std/submit-a-proposal steps, though my idea may break
old code so I'm currently just seeking to see if I'm missing something,
there's some existing proposal in this space, interest levels, and
hopefully a better idea!

The task: read numbers from a stream, print error message if there's bad
input

Commonly recommended approach:

    int n;
    while (stream >> n)
        ;
    if (!stream && !stream.eof())
        std::cerr << "choked on bad input\n";

Failing case: stream contains say "-", at least on the GCC compiler at
ideone.com the stream >> n operation sets *both *failbit and eofbit, as '-'
is consumed as a potentially valid part of a number that never materialises.

Available solution: you can use a controlling while (!(stream >>
std::ws).eof) then attempt stream >> n inside the loop, but that frustrates
the current ability to concisely express more complex multi-variable input
operations as chains of >> and short-circuited &&s with getline() and tests
of just-read variables.  Exceptions might be a valid solution here too, but
IMHO it's clearly undesirable that there not be an exception-free
alternative.

(Doomed) Proposal: the while (stream >> n) approach above could be made
more robust if the standard-library-provided overloads set only the failbit
in these circumstances, and left eof to be reported only if another input
operation is attempted.

Then for user-defined overloads, it'd be nice if beginners could be taught
something simple like:

    struct X { int a_, b_; };

    std::istream& operator>>(std::istream& is, const X& x)
    {
        return is >> x.a_ >> x.b_;
    }

But this may also leave the stream in a fail+eof condition - e.g.
istringstream("12") - where the caller can't differentiate "a" parsed
successfully but "b" failed from a simple eof for an empty/whitespace
stream.

Correct code - assuming the standard library's overload for int is adjusted
as proposed above - might be:

    std::istream& operator>>(std::istream& is, const X& x)
    {
        if (is >> x.a_)
            if (!(is >> x.b_))
            {
               is.clear(); // in case eof was set
               is.setstate(std::ios_base::failbit); // "just" fail
            }
        return is;
    }

Perhaps an iomanipulator could help here:

    std::istream& operator>>(std::istream& is, const X& x)
    {
        return is >> x.a_ >> x.b_ >> if_fail_clear_eof;
    }

And the doom and gloom: this would be a breaking change, so is probably a
non-started.  For example, someone dead-certain that their input was a
string of at least one space-separated numbers (with no trailing
whitespace), might currently get away with:

    while (!stream.eof()) { stream >> n; use(n); }

With the proposal above, the eof() wouldn't become true immediately after
streaming the last number.

Perhaps someone will have a better idea.  It bothers me that the common,
intuitive, expressive and concise approach can fail to notice parsing
errors....

Cheers,
Tony

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1848_1187062949.1424924977560
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello,<br><br>This is a "<strong>Float&nbsp;the idea" </st=
rong>post per the https://isocpp.org/std/submit-a-proposal steps, though my=
 idea may break old code so I'm currently just seeking to see if I'm missin=
g something, there's some existing proposal in this space, interest levels,=
 and hopefully a better idea!<br><br>The task: read numbers from a stream, =
print error message if there's bad input<br><br>Commonly recommended approa=
ch:<br><br>&nbsp; &nbsp; int n;<br>&nbsp;&nbsp;&nbsp; while (stream &gt;&gt=
; n)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>&nbsp;&nbsp;&nbsp; =
if (!stream &amp;&amp; !stream.eof())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp; std::cerr &lt;&lt; "choked on bad input\n";<br><br>Failing case: s=
tream contains say "-", at least on the GCC compiler at ideone.com the stre=
am &gt;&gt; n operation sets <i>both </i>failbit and eofbit, as '-' is cons=
umed as a potentially valid part of a number that never materialises.<br><b=
r>Available solution: you can use a controlling while (!(stream &gt;&gt; st=
d::ws).eof) then attempt stream &gt;&gt; n inside the loop, but that frustr=
ates the current ability to concisely express more complex multi-variable i=
nput operations as chains of &gt;&gt; and short-circuited &amp;&amp;s with =
getline() and tests of just-read variables.&nbsp; Exceptions might be a val=
id solution here too, but IMHO it's clearly undesirable that there not be a=
n exception-free alternative.<br><br>(Doomed) Proposal: the while (stream &=
gt;&gt; n) approach above could be made more robust if the standard-library=
-provided overloads set only the failbit in these circumstances, and left e=
of to be reported only if another input operation is attempted.<br><br>Then=
 for user-defined overloads, it'd be nice if beginners could be taught some=
thing simple like:<br><br>&nbsp;&nbsp;&nbsp; struct X { int a_, b_; };<br><=
br>&nbsp;&nbsp;&nbsp; std::istream&amp; operator&gt;&gt;(std::istream&amp; =
is, const X&amp; x)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; return is &gt;&gt; x.a_ &gt;&gt; x.b_;<br>&nbsp;&nbsp;&nbsp;=
 }<br><br>But this may also leave the stream in a fail+eof condition - e.g.=
 istringstream("12") - where the caller can't differentiate "a" parsed succ=
essfully but "b" failed from a simple eof for an empty/whitespace stream.<b=
r><br>Correct code - assuming the standard library's overload for int is ad=
justed as proposed above - might be:<br><br>&nbsp;&nbsp;&nbsp; std::istream=
&amp; operator&gt;&gt;(std::istream&amp; is, const X&amp; x)<br>&nbsp;&nbsp=
;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (is &gt;&gt; x.a=
_)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!(is &gt;&gt; x.b_))<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; is.clear(); // in case eof was set<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is.setstate(std::io=
s_base::failbit); // "just" fail<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 return is;<br>&nbsp;&nbsp;&nbsp; }<br><br>Perhaps an iomanipulator could h=
elp here:<br><br>&nbsp;&nbsp;&nbsp; std::istream&amp; operator&gt;&gt;(std:=
:istream&amp; is, const X&amp; x)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; return is &gt;&gt; x.a_ &gt;&gt; x.b_ &gt;&gt;=
 if_fail_clear_eof;<br>&nbsp;&nbsp;&nbsp; }<br><br>And the doom and gloom: =
this would be a breaking change, so is probably a non-started.&nbsp; For ex=
ample, someone dead-certain that their input was a string of at least one s=
pace-separated numbers (with no trailing whitespace), might currently get a=
way with:<br><br>&nbsp;&nbsp;&nbsp; while (!stream.eof()) { stream &gt;&gt;=
 n; use(n); }<br><br>With the proposal above, the eof() wouldn't become tru=
e immediately after streaming the last number.<br><br>Perhaps someone will =
have a better idea.&nbsp; It bothers me that the common, intuitive, express=
ive and concise approach can fail to notice parsing errors....<br><br>Cheer=
s,<br>Tony<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1848_1187062949.1424924977560--
------=_Part_1847_652735975.1424924977559--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 13:18:00 +0800
Raw View
--Apple-Mail=_98C206FF-5374-4CD0-AC18-DD8CD1F55AF3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 12:29 PM, anthonypon@gmail.com wrote:
>=20
> Hello,
>=20
> This is a "Float the idea" post per the https://isocpp.org/std/submit-a-p=
roposal steps, though my idea may break old code so I'm currently just seek=
ing to see if I'm missing something, there's some existing proposal in this=
 space, interest levels, and hopefully a better idea!
>=20
> The task: read numbers from a stream, print error message if there's bad =
input
>=20
> Commonly recommended approach:
>=20
>     int n;
>     while (stream >> n)
>         ;
>     if (!stream && !stream.eof())
>         std::cerr << "choked on bad input\n=E2=80=9D;

By whom? The most common recommendation I recall on this topic is, =E2=80=
=9Ceof() probably isn=E2=80=99t what you want.=E2=80=9D

To check for a failure due to bad input or parsing, use fail(). (And to che=
ck for an I/O error, use bad().) To check that the stream is emptied withou=
t error in general, use rdstate() =3D=3D std::ios::eofbit.

> Failing case: stream contains say "-", at least on the GCC compiler at id=
eone.com the stream >> n operation sets both failbit and eofbit, as '-' is =
consumed as a potentially valid part of a number that never materialises.

Unless you recognize the failure and seek the stream back before the dash (=
or somehow unget it), the condition is irrecoverable.

> Available solution: you can use a controlling while (!(stream >> std::ws)=
..eof)

In a loop, checking eof() is especially not to be encouraged.

> (Doomed) Proposal: the while (stream >> n) approach above could be made m=
ore robust if the standard-library-provided overloads set only the failbit =
in these circumstances, and left eof to be reported only if another input o=
peration is attempted.

Perhaps iostreams would be more robust if failed operations didn=E2=80=99t =
consume characters. It=E2=80=99s not particularly robust, or fast. Maybe it=
 can be replaced some day with something better.

But what robustness is added by clearing eof when no input remains? Any att=
empt to recover and re-read will just set eof() again.

>     while (!stream.eof()) { stream >> n; use(n); }

This is exactly what you should never do.

> With the proposal above, the eof() wouldn't become true immediately after=
 streaming the last number.
>=20
> Perhaps someone will have a better idea.  It bothers me that the common, =
intuitive, expressive and concise approach can fail to notice parsing error=
s=E2=80=A6.


Try this:

while (stream) { stream >> n; use(n); }
if (stream.fail()) std::cerr << "choked on bad input\n";
if (stream.bad()) std::cerr << "could not read the input\n";

Or more safely and lazily:

stream.exceptions( std::ios::failbit | std::ios::badbit );
while (stream) { stream >> n; use(n); }

Perhaps more folks would use automatic stream exceptions if they were more =
friendly. Here are some ideas:

1. Specify or recommend better default error messages for uncaught ios_base=
::failure exceptions.
2. Add a hook to ios_base::failure to add a user-visible file or stream nam=
e, let the standard streams initialize it in an unspecified way.
3. Create a sentry guard so you can set exceptions() at the beginning of a =
try block, and have it restored when it exits.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_98C206FF-5374-4CD0-AC18-DD8CD1F55AF3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 12:29 PM, <a href=3D"mailto:anthonypon@gmail.com" class=3D"=
">anthonypon@gmail.com</a> wrote:</div><br class=3D"Apple-interchange-newli=
ne"><div class=3D""><div dir=3D"ltr" class=3D"">Hello,<br class=3D""><br cl=
ass=3D"">This is a "<strong class=3D"">Float&nbsp;the idea" </strong>post p=
er the <a href=3D"https://isocpp.org/std/submit-a-proposal" class=3D"">http=
s://isocpp.org/std/submit-a-proposal</a> steps, though my idea may break ol=
d code so I'm currently just seeking to see if I'm missing something, there=
's some existing proposal in this space, interest levels, and hopefully a b=
etter idea!<br class=3D""><br class=3D"">The task: read numbers from a stre=
am, print error message if there's bad input<br class=3D""><br class=3D"">C=
ommonly recommended approach:<br class=3D""><br class=3D"">&nbsp; &nbsp; in=
t n;<br class=3D"">&nbsp;&nbsp;&nbsp; while (stream &gt;&gt; n)<br class=3D=
"">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br class=3D"">&nbsp;&nbsp;&=
nbsp; if (!stream &amp;&amp; !stream.eof())<br class=3D"">&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp; std::cerr &lt;&lt; "choked on bad input\n=E2=80=
=9D;<br class=3D""></div></div></blockquote><div><br class=3D""></div><div>=
By whom? The most common recommendation I recall on this topic is, =E2=80=
=9C<font face=3D"Courier" class=3D"">eof()</font> probably isn=E2=80=99t wh=
at you want.=E2=80=9D</div><div><br class=3D""></div><div>To check for a fa=
ilure due to bad input or parsing, use <font face=3D"Courier" class=3D"">fa=
il()</font>. (And to check for an I/O error, use <font face=3D"Courier" cla=
ss=3D"">bad()</font>.) To check that the stream is emptied without error in=
 general, use <font face=3D"Courier" class=3D"">rdstate() =3D=3D std::ios::=
eofbit</font>.</div><br class=3D""><blockquote type=3D"cite" class=3D""><di=
v class=3D""><div dir=3D"ltr" class=3D"">Failing case: stream contains say =
"-", at least on the GCC compiler at <a href=3D"http://ideone.com" class=3D=
"">ideone.com</a> the stream &gt;&gt; n operation sets <i class=3D"">both <=
/i>failbit and eofbit, as '-' is consumed as a potentially valid part of a =
number that never materialises.<br class=3D""></div></div></blockquote><div=
><br class=3D""></div>Unless you recognize the failure&nbsp;<i class=3D"">a=
nd</i>&nbsp;seek the stream back before the dash (or somehow unget it), the=
 condition is irrecoverable.</div><div><br class=3D""><blockquote type=3D"c=
ite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D"">Available solut=
ion: you can use a controlling while (!(stream &gt;&gt; std::ws).eof)</div>=
</div></blockquote><div><br class=3D""></div><div>In a loop, checking&nbsp;=
<span style=3D"font-family: Courier;" class=3D"">eof()</span>&nbsp;is espec=
ially not to be encouraged.</div><br class=3D""><blockquote type=3D"cite" c=
lass=3D""><div class=3D""><div dir=3D"ltr" class=3D"">(Doomed) Proposal: th=
e while (stream &gt;&gt; n) approach above could be made more robust if the=
 standard-library-provided overloads set only the failbit in these circumst=
ances, and left eof to be reported only if another input operation is attem=
pted.<br class=3D""></div></div></blockquote><div><br class=3D""></div><div=
>Perhaps iostreams would be more robust if failed operations didn=E2=80=99t=
 consume characters. It=E2=80=99s not particularly robust, or fast. Maybe i=
t can be replaced some day with something better.</div><div><br class=3D"">=
</div><div>But what robustness is added by clearing <font face=3D"Courier" =
class=3D"">eof</font> when no input remains? Any attempt to recover and re-=
read will just set <font face=3D"Courier" class=3D"">eof()</font> again.</d=
iv><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div=
 dir=3D"ltr" class=3D"">&nbsp; &nbsp; while (!stream.eof()) { stream &gt;&g=
t; n; use(n); }<br class=3D""></div></div></blockquote><div><br class=3D"">=
</div>This is exactly what you should never do.<br class=3D""><br class=3D"=
"><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" cla=
ss=3D"">With the proposal above, the eof() wouldn't become true immediately=
 after streaming the last number.<br class=3D""><br class=3D"">Perhaps some=
one will have a better idea.&nbsp; It bothers me that the common, intuitive=
, expressive and concise approach can fail to notice parsing errors=E2=80=
=A6.<br class=3D""></div></div></blockquote></div><div class=3D""><br class=
=3D""></div>Try this:<div class=3D""><br class=3D""></div><div class=3D""><=
font face=3D"Courier" class=3D"">while (stream) { stream &gt;&gt; n; use(n)=
; }<br class=3D""></font><div class=3D""><font face=3D"Courier" class=3D"">=
if (stream.fail()) std::cerr &lt;&lt; "choked on bad input\n";<br class=3D"=
">if (stream.bad()) std::cerr &lt;&lt; "could not read the input\n";<br cla=
ss=3D""></font></div></div><div class=3D""><br class=3D""></div><div class=
=3D"">Or more safely and lazily:</div><div class=3D""><br class=3D""></div>=
<div class=3D""><font face=3D"Courier" class=3D"">stream.exceptions( std::i=
os::failbit | std::ios::badbit );</font></div><div class=3D""><font face=3D=
"Courier" class=3D"">while (stream) { stream &gt;&gt; n; use(n); }<br class=
=3D""></font></div><div class=3D""><br class=3D""></div><div class=3D"">Per=
haps more folks would use automatic stream exceptions if they were more fri=
endly. Here are some ideas:</div><div class=3D""><br class=3D""></div><div =
class=3D"">1. Specify or recommend better default error messages for uncaug=
ht&nbsp;<span style=3D"font-family: Courier;" class=3D"">ios_base::failure<=
/span>&nbsp;exceptions.</div><div class=3D"">2. Add a hook to <font face=3D=
"Courier" class=3D"">ios_base::failure</font>&nbsp;to add a user-visible fi=
le or stream name, let the standard streams initialize it in an unspecified=
 way.</div><div class=3D"">3. Create a sentry guard so you can set <font fa=
ce=3D"Courier" class=3D"">exceptions()</font> at the beginning of a try blo=
ck, and have it restored when it exits.</div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_98C206FF-5374-4CD0-AC18-DD8CD1F55AF3--

.


Author: anthonypon@gmail.com
Date: Wed, 25 Feb 2015 23:26:19 -0800 (PST)
Raw View
------=_Part_375_1582696258.1424935579189
Content-Type: multipart/alternative;
 boundary="----=_Part_376_1643556464.1424935579189"

------=_Part_376_1643556464.1424935579189
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Thursday, February 26, 2015 at 2:18:13 PM UTC+9, David Krauss wrote:
>
>
> On 2015=E2=80=9302=E2=80=9326, at 12:29 PM, antho...@gmail.com <javascrip=
t:> wrote:
>
> Hello,
>
> This is a "*Float the idea" *post per the=20
> https://isocpp.org/std/submit-a-proposal steps, though my idea may break=
=20
> old code so I'm currently just seeking to see if I'm missing something,=
=20
> there's some existing proposal in this space, interest levels, and=20
> hopefully a better idea!
>
> The task: read numbers from a stream, print error message if there's bad=
=20
> input
>
> Commonly recommended approach:
>
>     int n;
>     while (stream >> n)
>         ;
>     if (!stream && !stream.eof())
>         std::cerr << "choked on bad input\n=E2=80=9D;
>
>
> By whom? The most common recommendation I recall on this topic is, =E2=80=
=9Ceof()=20
> probably isn=E2=80=99t what you want.=E2=80=9D
>
> To check for a failure due to bad input or parsing, use fail(). (And to=
=20
> check for an I/O error, use bad().) To check that the stream is emptied=
=20
> without error in general, use rdstate() =3D=3D std::ios::eofbit.
>
=20
The point is that fail() is set after stream >> n hits eof, without there=
=20
being "bad"/un-parsable input.
=20

> Failing case: stream contains say "-", at least on the GCC compiler at=20
> ideone.com the stream >> n operation sets *both *failbit and eofbit, as=
=20
> '-' is consumed as a potentially valid part of a number that never=20
> materialises.
>
>
> Unless you recognize the failure *and* seek the stream back before the=20
> dash (or somehow unget it), the condition is irrecoverable.
>

Exactly.  My point is: isn't that undesirable?  Shouldn't the library make=
=20
it easy to see why the loop terminated?

> Available solution: you can use a controlling while (!(stream >>=20
> std::ws).eof)
>
>
> In a loop, checking eof() is especially not to be encouraged.
>

 Agreed - it's in desperation that coders are forced back to this ugly and=
=20
error-prone mess.  Hence my original post.

> (Doomed) Proposal: the while (stream >> n) approach above could be made=
=20
> more robust if the standard-library-provided overloads set only the failb=
it=20
> in these circumstances, and left eof to be reported only if another input=
=20
> operation is attempted.
>
>
> Perhaps iostreams would be more robust if failed operations didn=E2=80=99=
t consume=20
> characters. It=E2=80=99s not particularly robust, or fast. Maybe it can b=
e replaced=20
> some day with something better.
>
> But what robustness is added by clearing eof when no input remains? Any=
=20
> attempt to recover and re-read will just set eof() again.
>

The robustness improvement comes from differentiating a stream of good=20
input from a stream terminated by bad (likely truncated in the case of "-")=
=20
input.  It's not about being able to get other input from the stream=20
afterwards; rather, one might print an error and terminate until the user=
=20
fixes the input instead of presenting results calculated from=20
bogus/incomplete input.
=20

>     while (!stream.eof()) { stream >> n; use(n); }
>
>
> This is exactly what you should never do.
>

That's not a particularly useful perspective.  I've presented it only to=20
illustrate currently working (but extremely fragile) code that would be=20
broken by this proposal.  Sure we can deride anyone silly enough to write=
=20
code like this (I certainly would in a code review), but it's still=20
important for me to acknowledge and illustrate how the proposal is a=20
breaking change.

> With the proposal above, the eof() wouldn't become true immediately after=
=20
> streaming the last number.
>
> Perhaps someone will have a better idea.  It bothers me that the common,=
=20
> intuitive, expressive and concise approach can fail to notice parsing=20
> errors=E2=80=A6.
>
>
> Try this:
>
> while (stream) { stream >> n; use(n); }
> if (stream.fail()) std::cerr << "choked on bad input\n";
> if (stream.bad()) std::cerr << "could not read the input\n";
>

=20
Tried here: http://ideone.com/BpKisk=20

Result: no warning for istringstream("2 3 -");
=20

> Or more safely and lazily:
>
> stream.exceptions( std::ios::failbit | std::ios::badbit );
> while (stream) { stream >> n; use(n); }
>
=20
That doesn't seem to work either - same terminating stream state for "3 4=
=20
-" and "3 4" - see http://ideone.com/UYKQiS
=20

> Perhaps more folks would use automatic stream exceptions if they were mor=
e=20
> friendly. Here are some ideas:
>
> 1. Specify or recommend better default error messages for uncaught=20
> ios_base::failure exceptions.
> 2. Add a hook to ios_base::failure to add a user-visible file or stream=
=20
> name, let the standard streams initialize it in an unspecified way.
> 3. Create a sentry guard so you can set exceptions() at the beginning of=
=20
> a try block, and have it restored when it exits.
>

Who could argue with better error messages?  Scope guards sound good too -=
=20
but easily implemented outside the Standard.  For 2 - if the exception's=20
caught in the scope containing the stream then it's not necessary, and if=
=20
not the stream's already destroyed.

Thanks for the input.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_376_1643556464.1424935579189
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 2:18:13 PM UTC+9=
, David Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div styl=
e=3D"word-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=
=E2=80=9302=E2=80=9326, at 12:29 PM, <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"s_GLHl1JFyoJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">antho...@gmail.com</a> wrote:</div><br><div><div dir=3D"ltr=
">Hello,<br><br>This is a "<b>Float&nbsp;the idea" </b>post per the <a href=
=3D"https://isocpp.org/std/submit-a-proposal" target=3D"_blank" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2=
F%2Fisocpp.org%2Fstd%2Fsubmit-a-proposal\46sa\75D\46sntz\0751\46usg\75AFQjC=
NGlLyCIYYQUZNTTJdUEpCYxvwG8Ig';return true;" onclick=3D"this.href=3D'https:=
//www.google.com/url?q\75https%3A%2F%2Fisocpp.org%2Fstd%2Fsubmit-a-proposal=
\46sa\75D\46sntz\0751\46usg\75AFQjCNGlLyCIYYQUZNTTJdUEpCYxvwG8Ig';return tr=
ue;">https://isocpp.org/std/submit-<wbr>a-proposal</a> steps, though my ide=
a may break old code so I'm currently just seeking to see if I'm missing so=
mething, there's some existing proposal in this space, interest levels, and=
 hopefully a better idea!<br><br>The task: read numbers from a stream, prin=
t error message if there's bad input<br><br>Commonly recommended approach:<=
br><br>&nbsp; &nbsp; int n;<br>&nbsp;&nbsp;&nbsp; while (stream &gt;&gt; n)=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>&nbsp;&nbsp;&nbsp; if (=
!stream &amp;&amp; !stream.eof())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp; std::cerr &lt;&lt; "choked on bad input\n=E2=80=9D;<br></div></div></b=
lockquote><div><br></div><div>By whom? The most common recommendation I rec=
all on this topic is, =E2=80=9C<font face=3D"Courier">eof()</font> probably=
 isn=E2=80=99t what you want.=E2=80=9D</div><div><br></div><div>To check fo=
r a failure due to bad input or parsing, use <font face=3D"Courier">fail()<=
/font>. (And to check for an I/O error, use <font face=3D"Courier">bad()</f=
ont>.) To check that the stream is emptied without error in general, use <f=
ont face=3D"Courier">rdstate() =3D=3D std::ios::eofbit</font>.</div></div><=
/div></blockquote><div>&nbsp;</div><div>The point is that fail() is set aft=
er stream &gt;&gt; n hits eof, without there being "bad"/un-parsable input.=
<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"=
word-wrap:break-word"><div><blockquote type=3D"cite"><div><div dir=3D"ltr">=
Failing case: stream contains say "-", at least on the GCC compiler at <a h=
ref=3D"http://ideone.com" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fideone.com\46sa\75=
D\46sntz\0751\46usg\75AFQjCNEgkElpZvlncw_m4nl7yXNHs2t0xA';return true;" onc=
lick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fideone.com\=
46sa\75D\46sntz\0751\46usg\75AFQjCNEgkElpZvlncw_m4nl7yXNHs2t0xA';return tru=
e;">ideone.com</a> the stream &gt;&gt; n operation sets <i>both </i>failbit=
 and eofbit, as '-' is consumed as a potentially valid part of a number tha=
t never materialises.<br></div></div></blockquote><div><br></div>Unless you=
 recognize the failure&nbsp;<i>and</i>&nbsp;seek the stream back before the=
 dash (or somehow unget it), the condition is irrecoverable.<br></div></div=
></blockquote><div><br>Exactly.&nbsp; My point is: isn't that undesirable?&=
nbsp; Shouldn't the library make it easy to see why the loop terminated?<br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap=
:break-word"><div><blockquote type=3D"cite"><div><div dir=3D"ltr">Available=
 solution: you can use a controlling while (!(stream &gt;&gt; std::ws).eof)=
</div></div></blockquote><div><br></div><div>In a loop, checking&nbsp;<span=
 style=3D"font-family:Courier">eof()</span>&nbsp;is especially not to be en=
couraged.</div></div></div></blockquote><div><br>&nbsp;Agreed - it's in des=
peration that coders are forced back to this ugly and error-prone mess.&nbs=
p; Hence my original post.<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite"><d=
iv><div dir=3D"ltr">(Doomed) Proposal: the while (stream &gt;&gt; n) approa=
ch above could be made more robust if the standard-library-provided overloa=
ds set only the failbit in these circumstances, and left eof to be reported=
 only if another input operation is attempted.<br></div></div></blockquote>=
<div><br></div><div>Perhaps iostreams would be more robust if failed operat=
ions didn=E2=80=99t consume characters. It=E2=80=99s not particularly robus=
t, or fast. Maybe it can be replaced some day with something better.</div><=
div><br></div><div>But what robustness is added by clearing <font face=3D"C=
ourier">eof</font> when no input remains? Any attempt to recover and re-rea=
d will just set <font face=3D"Courier">eof()</font> again.</div></div></div=
></blockquote><div><br>The robustness improvement comes from differentiatin=
g a stream of good input from a stream terminated by bad (likely truncated =
in the case of "-") input.&nbsp; It's not about being able to get other inp=
ut from the stream afterwards; rather, one might print an error and termina=
te until the user fixes the input instead of presenting results calculated =
from bogus/incomplete input.<br>&nbsp;</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"=
cite"><div><div dir=3D"ltr">&nbsp; &nbsp; while (!stream.eof()) { stream &g=
t;&gt; n; use(n); }<br></div></div></blockquote><div><br></div>This is exac=
tly what you should never do.<br></div></div></blockquote><div><br>That's n=
ot a particularly useful perspective.&nbsp; I've presented it only to illus=
trate currently working (but extremely fragile) code that would be broken b=
y this proposal.&nbsp; Sure we can deride anyone silly enough to write code=
 like this (I certainly would in a code review), but it's still important f=
or me to acknowledge and illustrate how the proposal is a breaking change.<=
br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word"><div><blockquote type=3D"cite"><div><div dir=3D"ltr">With th=
e proposal above, the eof() wouldn't become true immediately after streamin=
g the last number.<br><br>Perhaps someone will have a better idea.&nbsp; It=
 bothers me that the common, intuitive, expressive and concise approach can=
 fail to notice parsing errors=E2=80=A6.<br></div></div></blockquote></div>=
<div><br></div>Try this:<div><br></div><div><font face=3D"Courier">while (s=
tream) { stream &gt;&gt; n; use(n); }<br></font><div><font face=3D"Courier"=
>if (stream.fail()) std::cerr &lt;&lt; "choked on bad input\n";<br>if (stre=
am.bad()) std::cerr &lt;&lt; "could not read the input\n";<br></font></div>=
</div></div></blockquote><div><br>&nbsp;</div><div>Tried here: http://ideon=
e.com/BpKisk <br><br>Result: no warning for istringstream("2 3 -");<br>&nbs=
p;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wra=
p:break-word"><div></div><div>Or more safely and lazily:</div><div><br></di=
v><div><font face=3D"Courier">stream.exceptions( std::ios::failbit | std::i=
os::badbit );</font></div><div><font face=3D"Courier">while (stream) { stre=
am &gt;&gt; n; use(n); }<br></font></div></div></blockquote><div>&nbsp;</di=
v><div>That doesn't seem to work either - same terminating stream state for=
 "3 4 -" and "3 4" - see http://ideone.com/UYKQiS<br>&nbsp;</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div=
></div><div>Perhaps more folks would use automatic stream exceptions if the=
y were more friendly. Here are some ideas:</div><div><br></div><div>1. Spec=
ify or recommend better default error messages for uncaught&nbsp;<span styl=
e=3D"font-family:Courier">ios_base::failure</span>&nbsp;<wbr>exceptions.</d=
iv><div>2. Add a hook to <font face=3D"Courier">ios_base::failure</font>&nb=
sp;to add a user-visible file or stream name, let the standard streams init=
ialize it in an unspecified way.</div><div>3. Create a sentry guard so you =
can set <font face=3D"Courier">exceptions()</font> at the beginning of a tr=
y block, and have it restored when it exits.</div></div></blockquote><div><=
br>Who could argue with better error messages?&nbsp; Scope guards sound goo=
d too - but easily implemented outside the Standard.&nbsp; For 2 - if the e=
xception's caught in the scope containing the stream then it's not necessar=
y, and if not the stream's already destroyed.<br><br>Thanks for the input.<=
br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_376_1643556464.1424935579189--
------=_Part_375_1582696258.1424935579189--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 16:19:17 +0800
Raw View
--Apple-Mail=_068F36C4-9CCD-442C-84BF-9091A21FB9C0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 3:26 PM, anthonypon@gmail.com wrote:
>=20
> The point is that fail() is set after stream >> n hits eof, without there=
 being "bad"/un-parsable input.

There was bad input, the dash character. And your proposal is that eofbit s=
ometimes not be set at the EOF, not that failbit not be set after a convers=
ion failure.

If you=E2=80=99re concerned with conversion failures and not with eof, chec=
k failbit/fail() and not eofbit/eof().

> In a loop, checking eof() is especially not to be encouraged.
>=20
>  Agreed - it's in desperation that coders are forced back to this ugly an=
d error-prone mess.  Hence my original post.

There are right answers, albeit buried among wrong answers. That=E2=80=99s =
the way iostreams is, but this proposal seems to be shaking things up witho=
ut making correct code easier overall.

Again, though, eof() is seldom the right solution.

> The robustness improvement comes from differentiating a stream of good in=
put from a stream terminated by bad (likely truncated in the case of "-") i=
nput.  It's not about being able to get other input from the stream afterwa=
rds; rather, one might print an error and terminate until the user fixes th=
e input instead of presenting results calculated from bogus/incomplete inpu=
t.

Streams with bad input are differentiated by failbit. Period.

>>     while (!stream.eof()) { stream >> n; use(n); }
>=20
> This is exactly what you should never do.
>=20
> That's not a particularly useful perspective.  I've presented it only to =
illustrate currently working (but extremely fragile) code that would be bro=
ken by this proposal.  Sure we can deride anyone silly enough to write code=
 like this (I certainly would in a code review), but it's still important f=
or me to acknowledge and illustrate how the proposal is a breaking change.

Okay, but it looks similar to your first example, in that eof is being used=
 as a proxy for something else.

In this case, any conversion error leads to an infinite loop, which is extr=
a bad.

> Tried here: http://ideone.com/BpKisk <http://ideone.com/BpKisk>=20
>=20
> Result: no warning for istringstream("2 3 -=E2=80=9C);

The warning is printed there on the webpage under =E2=80=9Cstderr.=E2=80=9D

> Or more safely and lazily:
>=20
> stream.exceptions( std::ios::failbit | std::ios::badbit );
> while (stream) { stream >> n; use(n); }
> =20
> That doesn't seem to work either - same terminating stream state for "3 4=
 -" and "3 4" - see http://ideone.com/UYKQiS <http://ideone.com/UYKQiS>

Ah, I forgot that converting the stream to bool only tests failbit, not eof=
bit. Also, you need to manually eat the trailing space if it=E2=80=99s goin=
g to make a difference to the loop condition.

This is correct:

stream.exceptions( std::ios::failbit | std::ios::badbit );
while (stream.good()) { stream >> n >> std::ws; use(n); }

Yes, iostreams is finicky=E2=80=A6

> Perhaps more folks would use automatic stream exceptions if they were mor=
e friendly. Here are some ideas:
>=20
> 1. Specify or recommend better default error messages for uncaught ios_ba=
se::failure exceptions.
> 2. Add a hook to ios_base::failure to add a user-visible file or stream n=
ame, let the standard streams initialize it in an unspecified way.
> 3. Create a sentry guard so you can set exceptions() at the beginning of =
a try block, and have it restored when it exits.
>=20
> Who could argue with better error messages?  Scope guards sound good too =
- but easily implemented outside the Standard.  For 2 - if the exception's =
caught in the scope containing the stream then it's not necessary, and if n=
ot the stream's already destroyed.

#2 is more useful for proper I/O, not stringstreams. It can help a program =
generate a somewhat sensible error message for the user: =E2=80=9CExpected =
a number, got =E2=80=98z=E2=80=99 in HTTP POST input=E2=80=9D.

Point is, if the what() strings were more sensible, there would be less nee=
d to process the exceptions at all. Either generically catch after aborting=
 and print exc.what(), or don=E2=80=99t catch and let the program terminate=
, still getting a reasonable diagnostic log entry.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_068F36C4-9CCD-442C-84BF-9091A21FB9C0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 3:26 PM, <a href=3D"mailto:anthonypon@gmail.com" class=3D""=
>anthonypon@gmail.com</a> wrote:</div><br class=3D"Apple-interchange-newlin=
e"><div class=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; font-s=
ize: 12px; font-style: normal; font-variant: normal; font-weight: normal; l=
etter-spacing: normal; line-height: normal; orphans: auto; text-align: star=
t; text-indent: 0px; text-transform: none; white-space: normal; widows: aut=
o; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">The point=
 is that fail() is set after stream &gt;&gt; n hits eof, without there bein=
g "bad"/un-parsable input.</div></div></blockquote><div><br class=3D""></di=
v><div>There was bad input, the dash character. And your proposal is that e=
ofbit sometimes not be set at the EOF, not that failbit not be set after a =
conversion failure.</div><div><br class=3D""></div><div>If you=E2=80=99re c=
oncerned with conversion failures and not with eof, check failbit/fail() an=
d not eofbit/eof().</div><br class=3D""><blockquote type=3D"cite" class=3D"=
"><div dir=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; font-s=
tyle: normal; font-variant: normal; font-weight: normal; letter-spacing: no=
rmal; line-height: normal; orphans: auto; text-align: start; text-indent: 0=
px; text-transform: none; white-space: normal; widows: auto; word-spacing: =
0px; -webkit-text-stroke-width: 0px;" class=3D""><blockquote class=3D"gmail=
_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-=
left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex=
;"><div style=3D"word-wrap: break-word;" class=3D""><div class=3D""><div cl=
ass=3D"">In a loop, checking&nbsp;<span style=3D"font-family: Courier;" cla=
ss=3D"">eof()</span>&nbsp;is especially not to be encouraged.</div></div></=
div></blockquote><div class=3D""><br class=3D"">&nbsp;Agreed - it's in desp=
eration that coders are forced back to this ugly and error-prone mess.&nbsp=
; Hence my original post.<br class=3D""></div></div></blockquote><div><br c=
lass=3D""></div><div>There are right answers, albeit buried among wrong ans=
wers. That=E2=80=99s the way iostreams is, but this proposal seems to be sh=
aking things up without making correct code easier overall.</div><div><br c=
lass=3D""></div><div>Again, though, <font face=3D"Courier" class=3D"">eof()=
</font> is seldom the right solution.</div><br class=3D""><blockquote type=
=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" style=3D"font-family:=
 Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font=
-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto=
; text-align: start; text-indent: 0px; text-transform: none; white-space: n=
ormal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" cl=
ass=3D""><div class=3D"">The robustness improvement comes from differentiat=
ing a stream of good input from a stream terminated by bad (likely truncate=
d in the case of "-") input.&nbsp; It's not about being able to get other i=
nput from the stream afterwards; rather, one might print an error and termi=
nate until the user fixes the input instead of presenting results calculate=
d from bogus/incomplete input.<br class=3D""></div></div></div></blockquote=
><div><br class=3D""></div><div>Streams with bad input are differentiated b=
y <font face=3D"Courier" class=3D"">failbit</font>. Period.</div><br class=
=3D""><blockquote type=3D"cite" class=3D""><div dir=3D"ltr" style=3D"font-f=
amily: Helvetica; font-size: 12px; font-style: normal; font-variant: normal=
; font-weight: normal; letter-spacing: normal; line-height: normal; orphans=
: auto; text-align: start; text-indent: 0px; text-transform: none; white-sp=
ace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0p=
x;" class=3D""><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); bo=
rder-left-style: solid; padding-left: 1ex;"><div style=3D"word-wrap: break-=
word;" class=3D""><div class=3D""><blockquote type=3D"cite" class=3D""><div=
 class=3D""><div dir=3D"ltr" class=3D"">&nbsp; &nbsp; while (!stream.eof())=
 { stream &gt;&gt; n; use(n); }<br class=3D""></div></div></blockquote><div=
 class=3D""><br class=3D""></div>This is exactly what you should never do.<=
br class=3D""></div></div></blockquote><div class=3D""><br class=3D"">That'=
s not a particularly useful perspective.&nbsp; I've presented it only to il=
lustrate currently working (but extremely fragile) code that would be broke=
n by this proposal.&nbsp; Sure we can deride anyone silly enough to write c=
ode like this (I certainly would in a code review), but it's still importan=
t for me to acknowledge and illustrate how the proposal is a breaking chang=
e.<br class=3D""></div></div></blockquote><div><br class=3D""></div><div>Ok=
ay, but it looks similar to your first example, in that eof is being used a=
s a proxy for something else.</div><div><br class=3D""></div><div>In this c=
ase, any conversion error leads to an infinite loop, which is extra bad.</d=
iv><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div=
 dir=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; font-style: =
normal; font-variant: normal; font-weight: normal; letter-spacing: normal; =
line-height: normal; orphans: auto; text-align: start; text-indent: 0px; te=
xt-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -=
webkit-text-stroke-width: 0px;" class=3D""><div class=3D"">Tried here:<span=
 class=3D"Apple-converted-space">&nbsp;</span><a href=3D"http://ideone.com/=
BpKisk" class=3D"">http://ideone.com/BpKisk</a><span class=3D"Apple-convert=
ed-space">&nbsp;</span><br class=3D""><br class=3D"">Result: no warning for=
 istringstream("2 3 -=E2=80=9C);<br class=3D""></div></div></div></blockquo=
te><div><br class=3D""></div><div>The warning is printed there on the webpa=
ge under =E2=80=9Cstderr.=E2=80=9D</div><br class=3D""><blockquote type=3D"=
cite" class=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; font-siz=
e: 12px; font-style: normal; font-variant: normal; font-weight: normal; let=
ter-spacing: normal; line-height: normal; orphans: auto; text-align: start;=
 text-indent: 0px; text-transform: none; white-space: normal; widows: auto;=
 word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-widt=
h: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; pa=
dding-left: 1ex;"><div style=3D"word-wrap: break-word;" class=3D""><div cla=
ss=3D""></div><div class=3D"">Or more safely and lazily:</div><div class=3D=
""><br class=3D""></div><div class=3D""><font face=3D"Courier" class=3D"">s=
tream.exceptions( std::ios::failbit | std::ios::badbit );</font></div><div =
class=3D""><font face=3D"Courier" class=3D"">while (stream) { stream &gt;&g=
t; n; use(n); }<br class=3D""></font></div></div></blockquote><div class=3D=
"">&nbsp;</div><div class=3D"">That doesn't seem to work either - same term=
inating stream state for "3 4 -" and "3 4" - see<span class=3D"Apple-conver=
ted-space">&nbsp;</span><a href=3D"http://ideone.com/UYKQiS" class=3D"">htt=
p://ideone.com/UYKQiS</a><br class=3D""></div></div></blockquote><div><br c=
lass=3D""></div><div>Ah, I forgot that converting the stream to bool only t=
ests failbit, not eofbit. Also, you need to manually eat the trailing space=
 if it=E2=80=99s going to make a difference to the loop condition.</div><di=
v><br class=3D""></div><div>This is correct:</div><div><br class=3D""></div=
><div><font face=3D"Courier" class=3D"">stream.exceptions( std::ios::failbi=
t | std::ios::badbit );</font></div><div><font face=3D"Courier" class=3D"">=
while (stream.good()) { stream &gt;&gt; n &gt;&gt; std::ws; use(n); }<br cl=
ass=3D""></font><br class=3D""></div><div>Yes, iostreams is finicky=E2=80=
=A6</div><br class=3D""><blockquote type=3D"cite" class=3D""><div dir=3D"lt=
r" style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; fo=
nt-variant: normal; font-weight: normal; letter-spacing: normal; line-heigh=
t: normal; orphans: auto; text-align: start; text-indent: 0px; text-transfo=
rm: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-tex=
t-stroke-width: 0px;" class=3D""><blockquote class=3D"gmail_quote" style=3D=
"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(=
204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style=3D=
"word-wrap: break-word;" class=3D""><div class=3D""></div><div class=3D"">P=
erhaps more folks would use automatic stream exceptions if they were more f=
riendly. Here are some ideas:</div><div class=3D""><br class=3D""></div><di=
v class=3D"">1. Specify or recommend better default error messages for unca=
ught&nbsp;<span style=3D"font-family: Courier;" class=3D"">ios_base::failur=
e</span>&nbsp;<wbr class=3D"">exceptions.</div><div class=3D"">2. Add a hoo=
k to<span class=3D"Apple-converted-space">&nbsp;</span><font face=3D"Courie=
r" class=3D"">ios_base::failure</font>&nbsp;to add a user-visible file or s=
tream name, let the standard streams initialize it in an unspecified way.</=
div><div class=3D"">3. Create a sentry guard so you can set<span class=3D"A=
pple-converted-space">&nbsp;</span><font face=3D"Courier" class=3D"">except=
ions()</font><span class=3D"Apple-converted-space">&nbsp;</span>at the begi=
nning of a try block, and have it restored when it exits.</div></div></bloc=
kquote><div class=3D""><br class=3D"">Who could argue with better error mes=
sages?&nbsp; Scope guards sound good too - but easily implemented outside t=
he Standard.&nbsp; For 2 - if the exception's caught in the scope containin=
g the stream then it's not necessary, and if not the stream's already destr=
oyed.<br class=3D""></div></div></blockquote><div><br class=3D""></div><div=
>#2 is more useful for proper I/O, not stringstreams. It can help a program=
 generate a somewhat sensible error message for the user: =E2=80=9CExpected=
 a number, got =E2=80=98z=E2=80=99 in HTTP POST input=E2=80=9D.</div><div><=
br class=3D""></div><div>Point is, if the what() strings were more sensible=
, there would be less need to process the exceptions at all. Either generic=
ally catch after aborting and print exc.what(), or don=E2=80=99t catch and =
let the program terminate, still getting a reasonable diagnostic log entry.=
</div></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_068F36C4-9CCD-442C-84BF-9091A21FB9C0--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 26 Feb 2015 00:28:59 -0800 (PST)
Raw View
------=_Part_10_92763639.1424939339136
Content-Type: multipart/alternative;
 boundary="----=_Part_11_5352951.1424939339136"

------=_Part_11_5352951.1424939339136
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le jeudi 26 f=C3=A9vrier 2015 08:26:19 UTC+1, antho...@gmail.com a =C3=A9cr=
it :
>
>
>
> On Thursday, February 26, 2015 at 2:18:13 PM UTC+9, David Krauss wrote:
>>
>>
>> On 2015=E2=80=9302=E2=80=9326, at 12:29 PM, antho...@gmail.com wrote:
>>
>> Hello,
>>
>> This is a "*Float the idea" *post per the=20
>> https://isocpp.org/std/submit-a-proposal steps, though my idea may break=
=20
>> old code so I'm currently just seeking to see if I'm missing something,=
=20
>> there's some existing proposal in this space, interest levels, and=20
>> hopefully a better idea!
>>
>> The task: read numbers from a stream, print error message if there's bad=
=20
>> input
>>
>> Commonly recommended approach:
>>
>>     int n;
>>     while (stream >> n)
>>         ;
>>     if (!stream && !stream.eof())
>>         std::cerr << "choked on bad input\n=E2=80=9D;
>>
>>
>> By whom? The most common recommendation I recall on this topic is, =E2=
=80=9Ceof()=20
>> probably isn=E2=80=99t what you want.=E2=80=9D
>>
>> To check for a failure due to bad input or parsing, use fail(). (And to=
=20
>> check for an I/O error, use bad().) To check that the stream is emptied=
=20
>> without error in general, use rdstate() =3D=3D std::ios::eofbit.
>>
> =20
> The point is that fail() is set after stream >> n hits eof, without there=
=20
> being "bad"/un-parsable input.
>

You tried to input something, that input failed.  There is indeed no=20
difference between failing due to missing data and bad data with >> if you=
=20
automatically skip over the whitespace. If you want to do so, you'll have=
=20
to skip the white space manually (and disable the possibility to skip=20
automatically, ws is using the sentry which set the error)

    stream >> std::noskipws;
    while (stream >> std::ws && !stream.eof() && stream >> n) {
        std::cout << "got " << n << '\n';
    }
    if (stream.bad()) std::cout << "IO error\n";
    if (stream.fail()) std::cout << "Bad format\n";

Usually, the distinction doesn't worth the pain (maybe because I share with=
=20
the IOStream designers an Unix bias, Unix considers `\n` as line terminator=
=20
so non terminated last lines are oddities which can be ignored when=20
IOStream formatted input is an adequate mechanism). When I use formatted=20
IOstream input, I use this kind of loop:

    while (stream >> n) {
        std::cout << "got " << n << '\n';
    }
    if (stream.bad()) std::cout << "IO error\n";
    if (!stream.eof()) std::cout << "Bad format\n";

=20
>
>> Failing case: stream contains say "-", at least on the GCC compiler at=
=20
>> ideone.com the stream >> n operation sets *both *failbit and eofbit, as=
=20
>> '-' is consumed as a potentially valid part of a number that never=20
>> materialises.
>>
>>
>> Unless you recognize the failure *and* seek the stream back before the=
=20
>> dash (or somehow unget it), the condition is irrecoverable.
>>
>
> Exactly.  My point is: isn't that undesirable?  Shouldn't the library mak=
e=20
> it easy to see why the loop terminated?
>

If you go to the point where error recovery is needed, IOStream formatted=
=20
input is probably no more an adequate solution.


>> Try this:
>>
>> while (stream) { stream >> n; use(n); }
>>
>
That's wrong: never use the result of an IO operation without being sure=20
that the IO operation succeeded.

Yours,

--=20
Jean-Marc

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_11_5352951.1424939339136
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le jeudi 26 f=C3=A9vrier 2015 08:26:19 UTC+1, antho...@gma=
il.com a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
 dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 2:18:13 PM UTC+9, Da=
vid Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word=
-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=E2=80=930=
2=E2=80=9326, at 12:29 PM, <a rel=3D"nofollow">antho...@gmail.com</a> wrote=
:</div><br><div><div dir=3D"ltr">Hello,<br><br>This is a "<b>Float&nbsp;the=
 idea" </b>post per the <a href=3D"https://isocpp.org/std/submit-a-proposal=
" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://ww=
w.google.com/url?q\75https%3A%2F%2Fisocpp.org%2Fstd%2Fsubmit-a-proposal\46s=
a\75D\46sntz\0751\46usg\75AFQjCNGlLyCIYYQUZNTTJdUEpCYxvwG8Ig';return true;"=
 onclick=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fisocp=
p.org%2Fstd%2Fsubmit-a-proposal\46sa\75D\46sntz\0751\46usg\75AFQjCNGlLyCIYY=
QUZNTTJdUEpCYxvwG8Ig';return true;">https://isocpp.org/std/submit-<wbr>a-pr=
oposal</a> steps, though my idea may break old code so I'm currently just s=
eeking to see if I'm missing something, there's some existing proposal in t=
his space, interest levels, and hopefully a better idea!<br><br>The task: r=
ead numbers from a stream, print error message if there's bad input<br><br>=
Commonly recommended approach:<br><br>&nbsp; &nbsp; int n;<br>&nbsp;&nbsp;&=
nbsp; while (stream &gt;&gt; n)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p; ;<br>&nbsp;&nbsp;&nbsp; if (!stream &amp;&amp; !stream.eof())<br>&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cerr &lt;&lt; "choked on bad input=
\n=E2=80=9D;<br></div></div></blockquote><div><br></div><div>By whom? The m=
ost common recommendation I recall on this topic is, =E2=80=9C<font face=3D=
"Courier">eof()</font> probably isn=E2=80=99t what you want.=E2=80=9D</div>=
<div><br></div><div>To check for a failure due to bad input or parsing, use=
 <font face=3D"Courier">fail()</font>. (And to check for an I/O error, use =
<font face=3D"Courier">bad()</font>.) To check that the stream is emptied w=
ithout error in general, use <font face=3D"Courier">rdstate() =3D=3D std::i=
os::eofbit</font>.</div></div></div></blockquote><div>&nbsp;</div><div>The =
point is that fail() is set after stream &gt;&gt; n hits eof, without there=
 being "bad"/un-parsable input.<br></div></div></blockquote><div><br></div>=
<div>You tried to input something, that input failed. &nbsp;There is indeed=
 no difference between failing due to missing data and bad data with &gt;&g=
t; if you automatically skip over the whitespace. If you want to do so, you=
'll have to skip the white space manually (and disable the possibility to s=
kip automatically, ws is using the sentry which set the error)</div><div><b=
r></div><div>&nbsp; &nbsp; stream &gt;&gt; std::noskipws;</div><div>&nbsp; =
&nbsp; while (stream &gt;&gt; std::ws &amp;&amp; !stream.eof() &amp;&amp; s=
tream &gt;&gt; n) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; std::cout &lt;&lt=
; "got " &lt;&lt; n &lt;&lt; '\n';</div><div>&nbsp; &nbsp; }</div><div>&nbs=
p; &nbsp; if (stream.bad()) std::cout &lt;&lt; "IO error\n";</div><div>&nbs=
p; &nbsp; if (stream.fail()) std::cout &lt;&lt; "Bad format\n";</div><div><=
br></div><div>Usually, the distinction doesn't worth the pain (maybe becaus=
e I share with the IOStream designers an Unix bias, Unix considers `\n` as =
line terminator so non terminated last lines are oddities which can be igno=
red when IOStream formatted input is an adequate mechanism). When I use for=
matted IOstream input, I use this kind of loop:</div><div><div><br></div><d=
iv>&nbsp; &nbsp; while (stream &gt;&gt; n) {</div><div>&nbsp; &nbsp; &nbsp;=
 &nbsp; std::cout &lt;&lt; "got " &lt;&lt; n &lt;&lt; '\n';</div><div>&nbsp=
; &nbsp; }</div><div>&nbsp; &nbsp; if (stream.bad()) std::cout &lt;&lt; "IO=
 error\n";</div><div>&nbsp; &nbsp; if (!stream.eof()) std::cout &lt;&lt; "B=
ad format\n";</div></div><div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div>&nbsp;</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite"=
><div><div dir=3D"ltr">Failing case: stream contains say "-", at least on t=
he GCC compiler at <a href=3D"http://ideone.com" rel=3D"nofollow" target=3D=
"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%=
2F%2Fideone.com\46sa\75D\46sntz\0751\46usg\75AFQjCNEgkElpZvlncw_m4nl7yXNHs2=
t0xA';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fideone.com\46sa\75D\46sntz\0751\46usg\75AFQjCNEgkElpZvlncw_m4nl=
7yXNHs2t0xA';return true;">ideone.com</a> the stream &gt;&gt; n operation s=
ets <i>both </i>failbit and eofbit, as '-' is consumed as a potentially val=
id part of a number that never materialises.<br></div></div></blockquote><d=
iv><br></div>Unless you recognize the failure&nbsp;<i>and</i>&nbsp;seek the=
 stream back before the dash (or somehow unget it), the condition is irreco=
verable.<br></div></div></blockquote><div><br>Exactly.&nbsp; My point is: i=
sn't that undesirable?&nbsp; Shouldn't the library make it easy to see why =
the loop terminated?<br></div></div></blockquote><div><br></div><div>If you=
 go to the point where error recovery is needed, IOStream formatted input i=
s probably no more an adequate solution.</div><div><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div style=3D"word-wrap:break-word"><div><br></div>Try this:<d=
iv><br></div><div><font face=3D"Courier">while (stream) { stream &gt;&gt; n=
; use(n); }<br></font></div></div></blockquote></div></blockquote><div><br>=
</div><div>That's wrong: never use the result of an IO operation without be=
ing sure that the IO operation succeeded.</div><div><br></div><div>Yours,</=
div><div><br></div><div>--&nbsp;</div><div>Jean-Marc</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_11_5352951.1424939339136--
------=_Part_10_92763639.1424939339136--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 16:34:22 +0800
Raw View
--Apple-Mail=_BE5148DF-A1CE-4D71-83E5-04B1792A3D97
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 4:28 PM, Jean-Marc Bourguet <jm.bourgue=
t@gmail.com> wrote:
>=20
> while (stream) { stream >> n; use(n); }
>=20
> That's wrong: never use the result of an IO operation without being sure =
that the IO operation succeeded.

Yikes, sorry, missed that when editing the example.

Failure conditions are much better handled as exceptions IMHO.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_BE5148DF-A1CE-4D71-83E5-04B1792A3D97
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 4:28 PM, Jean-Marc Bourguet &lt;<a href=3D"mailto:jm.bourgu=
et@gmail.com" class=3D"">jm.bourguet@gmail.com</a>&gt; wrote:</div><div cla=
ss=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; =
font-style: normal; font-variant: normal; font-weight: normal; letter-spaci=
ng: normal; line-height: normal; orphans: auto; text-align: start; text-ind=
ent: 0px; text-transform: none; white-space: normal; widows: auto; word-spa=
cing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><div class=3D""><br =
class=3D""></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); =
border-left-style: solid; padding-left: 1ex;"><div dir=3D"ltr" class=3D""><=
blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border=
-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style:=
 solid; padding-left: 1ex;"><div style=3D"word-wrap: break-word;" class=3D"=
"><div class=3D""><span style=3D"font-family: Courier;" class=3D"">while (s=
tream) { stream &gt;&gt; n; use(n); }</span></div></div></blockquote></div>=
</blockquote><div class=3D""><br class=3D""></div><div class=3D"">That's wr=
ong: never use the result of an IO operation without being sure that the IO=
 operation succeeded.</div></div></div></blockquote><div><br class=3D""></d=
iv><div>Yikes, sorry, missed that when editing the example.</div><div><br c=
lass=3D""></div><div>Failure conditions are much better handled as exceptio=
ns IMHO.</div></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_BE5148DF-A1CE-4D71-83E5-04B1792A3D97--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 26 Feb 2015 09:36:11 +0100
Raw View
--001a11346da84d3c2a050ff9a77b
Content-Type: text/plain; charset=UTF-8

On 26 February 2015 at 09:34, David Krauss <potswa@gmail.com> wrote:

> Failure conditions are much better handled as exceptions IMHO.
>

What about logging from destructors?
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11346da84d3c2a050ff9a77b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra">On 26 February 2015 at 09:34, D=
avid Krauss <span dir=3D"ltr">&lt;<a href=3D"mailto:potswa@gmail.com" targe=
t=3D"_blank">potswa@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_=
quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><=
div><div>Failure conditions are much better handled as exceptions IMHO.</di=
v></div></div></blockquote><div><br></div><div>What about logging from dest=
ructors?=C2=A0</div></div>-- <br><div class=3D"gmail_signature">=C2=A0Nevin=
 &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlor=
d.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=C2=A0 (847) 691-140=
4</div>
</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11346da84d3c2a050ff9a77b--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 26 Feb 2015 00:46:59 -0800 (PST)
Raw View
------=_Part_109_389688866.1424940419107
Content-Type: multipart/alternative;
 boundary="----=_Part_110_1823131159.1424940419107"

------=_Part_110_1823131159.1424940419107
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le jeudi 26 f=C3=A9vrier 2015 09:19:29 UTC+1, David Krauss a =C3=A9crit :
>
>
> This is correct:
>

Well ;-)=20


> stream.exceptions( std::ios::failbit | std::ios::badbit );
> while (stream.good()) { stream >> n >> std::ws; use(n); }
>
> Yes, iostreams is finicky=E2=80=A6
>

Tricky indeed.  You have to remove the possibility to skip whitespace=20
automatically as std::ws is using the sentry which will first skip and then=
=20
set the failbit at eof and thus throw an exception before ws skip without=
=20
setting failbit.

stream >> std::noskipws;
stream.exceptions( std::ios::failbit | std::ios::badbit );
while (stream >> std::ws >> n) { use(n); }

seems good.

--=20
Jean-Marc

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_110_1823131159.1424940419107
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le jeudi 26 f=C3=A9vrier 2015 09:19:29 UTC+1, David Krauss=
 a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=
=3D"word-wrap:break-word"><div><div><br></div><div>This is correct:</div></=
div></div></blockquote><div><br></div><div>Well ;-)&nbsp;</div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:bre=
ak-word"><div><div><br></div><div><font face=3D"Courier">stream.exceptions(=
 std::ios::failbit | std::ios::badbit );</font></div><div><font face=3D"Cou=
rier">while (stream.good()) { stream &gt;&gt; n &gt;&gt; std::ws; use(n); }=
<br></font><br></div><div>Yes, iostreams is finicky=E2=80=A6</div></div></d=
iv></blockquote><div><br></div><div>Tricky indeed. &nbsp;You have to remove=
 the possibility to skip whitespace automatically as std::ws is using the s=
entry which will first skip and then set the failbit at eof and thus throw =
an exception before ws skip without setting failbit.</div><div><br></div><d=
iv>stream &gt;&gt; std::noskipws;</div><div><span style=3D"font-family: Cou=
rier;">stream.exceptions( std::ios::failbit | std::ios::badbit );</span><br=
></div><div><span style=3D"font-family: Courier;">while (stream &gt;&gt; st=
d::ws &gt;&gt; n) { use(n); }</span></div><div><span style=3D"font-family: =
Courier;"><br></span></div><div><span style=3D"font-family: Courier;">seems=
 good.</span></div><div><span style=3D"font-family: Courier;"><br></span></=
div><div><span style=3D"font-family: Courier;">--&nbsp;</span></div><div><s=
pan style=3D"font-family: Courier;">Jean-Marc</span></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_110_1823131159.1424940419107--
------=_Part_109_389688866.1424940419107--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 26 Feb 2015 00:49:39 -0800 (PST)
Raw View
------=_Part_83_1946931541.1424940579719
Content-Type: multipart/alternative;
 boundary="----=_Part_84_870080248.1424940579719"

------=_Part_84_870080248.1424940579719
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



Le jeudi 26 f=C3=A9vrier 2015 09:36:57 UTC+1, Nevin ":-)" Liber a =C3=A9cri=
t :
>
> On 26 February 2015 at 09:34, David Krauss <pot...@gmail.com <javascript:=
>
> > wrote:
>
>> Failure conditions are much better handled as exceptions IMHO.
>>
>
> What about logging from destructors?=20
>
>
Wrap the destructor in a try {} catch block? (Logging rarely ask for input=
=20
parsing BTW, and the error condition for output are even better handled by=
=20
exception than those for input, they are order of magnitude rarer and more=
=20
difficult to test).

Yours,

--=20
Jean-Marc

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_84_870080248.1424940579719
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le jeudi 26 f=C3=A9vrier 2015 09:36:57 UTC+1, Nevi=
n ":-)" Liber a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">On 26 February 2015 at 09:34, David Krauss <span dir=3D=
"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"WAxQDsCo9k4J" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:'=
;return true;" onclick=3D"this.href=3D'javascript:';return true;">pot...@gm=
ail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_quote"><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div style=3D"word-wrap:break-word"><div><div>Failure condi=
tions are much better handled as exceptions IMHO.</div></div></div></blockq=
uote><div><br></div><div>What about logging from destructors?&nbsp;</div></=
div><br></div></blockquote><div><br></div><div>Wrap the destructor in a try=
 {} catch block? (Logging rarely ask for input parsing BTW, and the error c=
ondition for output are even better handled by exception than those for inp=
ut, they are order of magnitude rarer and more difficult to test).</div><di=
v><br></div><div>Yours,</div><div><br></div><div>--&nbsp;</div><div>Jean-Ma=
rc</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_84_870080248.1424940579719--
------=_Part_83_1946931541.1424940579719--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 16:53:58 +0800
Raw View
--Apple-Mail=_0C824361-6393-4721-8D82-E831A8E29068
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 4:36 PM, Nevin Liber <nevin@eviloverlor=
d.com> wrote:
>=20
> On 26 February 2015 at 09:34, David Krauss <potswa@gmail.com <mailto:pots=
wa@gmail.com>> wrote:
> Failure conditions are much better handled as exceptions IMHO.
>=20
> What about logging from destructors?=20

What about it? If you mean that it=E2=80=99s dangerous for std::clog << foo=
 to throw, then just don=E2=80=99t set clog.exceptions!

On the other hand, if you have a transaction object which wishes to log som=
ething from its destructor, then it might be easier to reliably detect the =
failure during unwinding, as opposed to upon exiting the non-exceptional sc=
ope with a neutered stream and a bunch of uninitialized variables.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_0C824361-6393-4721-8D82-E831A8E29068
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 4:36 PM, Nevin Liber &lt;<a href=3D"mailto:nevin@eviloverlo=
rd.com" class=3D"">nevin@eviloverlord.com</a>&gt; wrote:</div><br class=3D"=
Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D""><div=
 class=3D"gmail_extra">On 26 February 2015 at 09:34, David Krauss <span dir=
=3D"ltr" class=3D"">&lt;<a href=3D"mailto:potswa@gmail.com" target=3D"_blan=
k" class=3D"">potswa@gmail.com</a>&gt;</span> wrote:<br class=3D""><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:b=
reak-word" class=3D""><div class=3D""><div class=3D"">Failure conditions ar=
e much better handled as exceptions IMHO.</div></div></div></blockquote><di=
v class=3D""><br class=3D""></div><div class=3D"">What about logging from d=
estructors?&nbsp;</div></div></div></div></div></blockquote><div><br class=
=3D""></div><div>What about it? If you mean that it=E2=80=99s dangerous for=
&nbsp;<font face=3D"Courier" class=3D"">std::clog &lt;&lt; foo</font>&nbsp;=
to throw, then just don=E2=80=99t set <font face=3D"Courier" class=3D"">clo=
g.exceptions</font>!</div><div><br class=3D""></div><div>On the other hand,=
 if you have a transaction object which wishes to log something from its de=
structor, then it might be easier to reliably detect the failure during unw=
inding, as opposed to upon exiting the non-exceptional scope with a neutere=
d stream and a bunch of uninitialized variables.</div></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_0C824361-6393-4721-8D82-E831A8E29068--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 26 Feb 2015 10:04:14 +0100
Raw View
--089e013d1470994e7b050ffa0b34
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 26 February 2015 at 09:53, David Krauss <potswa@gmail.com> wrote:

>
> On 2015=E2=80=9302=E2=80=9326, at 4:36 PM, Nevin Liber <nevin@eviloverlor=
d.com> wrote:
>
> On 26 February 2015 at 09:34, David Krauss <potswa@gmail.com> wrote:
>
>> Failure conditions are much better handled as exceptions IMHO.
>>
>
> What about logging from destructors?
>
>
> What about it? If you mean that it=E2=80=99s dangerous for std::clog << f=
oo to
> throw, then just don=E2=80=99t set clog.exceptions!
>
> On the other hand, if you have a transaction object which wishes to log
> something from its destructor, then it might be easier to reliably detect
> the failure during unwinding, as opposed to upon exiting the
> non-exceptional scope with a neutered stream and a bunch of uninitialized
> variables.
>

It is a truly horrible idea to encourage people to use exceptions in
libraries that are likely to be called from destructors.  Wrapping
everything in a destructor in a try..catch block is a usability nightmare.
And making error handling *inconsistent* input vs. output for the *same*
library (it is supposed to be one combined library) would be a strictly
worse choice.

Might as well just go back to using printf/scanf...
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--089e013d1470994e7b050ffa0b34
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 26 February 2015 at 09:53, David Krauss <span dir=3D"lt=
r">&lt;<a href=3D"mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.c=
om</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><=
br><div><span class=3D""><blockquote type=3D"cite"><div>On 2015=E2=80=9302=
=E2=80=9326, at 4:36 PM, Nevin Liber &lt;<a href=3D"mailto:nevin@eviloverlo=
rd.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt; wrote:</div><br><d=
iv><div dir=3D"ltr"><div class=3D"gmail_extra">On 26 February 2015 at 09:34=
, David Krauss <span dir=3D"ltr">&lt;<a href=3D"mailto:potswa@gmail.com" ta=
rget=3D"_blank">potswa@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gma=
il_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word=
"><div><div>Failure conditions are much better handled as exceptions IMHO.<=
/div></div></div></blockquote><div><br></div><div>What about logging from d=
estructors?=C2=A0</div></div></div></div></div></blockquote><div><br></div>=
</span><div>What about it? If you mean that it=E2=80=99s dangerous for=C2=
=A0<font face=3D"Courier">std::clog &lt;&lt; foo</font>=C2=A0to throw, then=
 just don=E2=80=99t set <font face=3D"Courier">clog.exceptions</font>!</div=
><div><br></div><div>On the other hand, if you have a transaction object wh=
ich wishes to log something from its destructor, then it might be easier to=
 reliably detect the failure during unwinding, as opposed to upon exiting t=
he non-exceptional scope with a neutered stream and a bunch of uninitialize=
d variables.</div></div></div></blockquote><div><br></div><div>It is a trul=
y horrible idea to encourage people to use exceptions in libraries that are=
 likely to be called from destructors.=C2=A0 Wrapping everything in a destr=
uctor in a try..catch block is a usability nightmare.=C2=A0 And making erro=
r handling <i>inconsistent</i>=C2=A0input vs. output for the <i>same</i> li=
brary (it is supposed to be one combined library) would be a strictly worse=
 choice.</div><div><br></div><div>Might as well just go back to using print=
f/scanf...</div></div>-- <br><div class=3D"gmail_signature">=C2=A0Nevin &qu=
ot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.co=
m" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=C2=A0 (847) 691-1404</d=
iv>
</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e013d1470994e7b050ffa0b34--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 17:06:37 +0800
Raw View
--Apple-Mail=_E3EF2884-B04D-44AE-984E-F9016B19F703
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 4:46 PM, Jean-Marc Bourguet <jm.bourgue=
t@gmail.com> wrote:
>=20
> Tricky indeed.  You have to remove the possibility to skip whitespace aut=
omatically as std::ws is using the sentry which will first skip and then se=
t the failbit at eof and thus throw an exception before ws skip without set=
ting failbit.
>=20
> stream >> std::noskipws;
> stream.exceptions( std::ios::failbit | std::ios::badbit );
> while (stream >> std::ws >> n) { use(n); }
>=20
> seems good.

What if there=E2=80=99s whitespace after the number; is that also failure?

It looks like the manual whitespace handling in this example is only doing =
the same thing as the sentry would have.

How about:

while ( (stream >> std::ws).good() && stream >> n ) use( n );

This loop will exit upon EOF, with stream =3D=3D true, or failure, with str=
eam =3D=3D false.

Or, how about not using iostreams where tolerance and precise distinctions =
are needed ;P .

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_E3EF2884-B04D-44AE-984E-F9016B19F703
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 4:46 PM, Jean-Marc Bourguet &lt;<a href=3D"mailto:jm.bourgu=
et@gmail.com" class=3D"">jm.bourguet@gmail.com</a>&gt; wrote:</div><br clas=
s=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D""=
><div class=3D"">Tricky indeed. &nbsp;You have to remove the possibility to=
 skip whitespace automatically as std::ws is using the sentry which will fi=
rst skip and then set the failbit at eof and thus throw an exception before=
 ws skip without setting failbit.</div><div class=3D""><br class=3D""></div=
><div class=3D"">stream &gt;&gt; std::noskipws;</div><div class=3D""><span =
style=3D"font-family: Courier;" class=3D"">stream.exceptions( std::ios::fai=
lbit | std::ios::badbit );</span><br class=3D""></div><div class=3D""><span=
 style=3D"font-family: Courier;" class=3D"">while (stream &gt;&gt; std::ws =
&gt;&gt; n) { use(n); }</span></div><div class=3D""><span style=3D"font-fam=
ily: Courier;" class=3D""><br class=3D""></span></div><div class=3D""><span=
 style=3D"font-family: Courier;" class=3D"">seems good.</span></div></div><=
/div></blockquote><div><br class=3D""></div><div>What if there=E2=80=99s wh=
itespace after the number; is that also failure?</div><div><br class=3D""><=
/div><div>It looks like the manual whitespace handling in this example is o=
nly doing the same thing as the sentry would have.</div><div><br class=3D""=
></div><div>How about:</div><div><br class=3D""></div><div><font face=3D"Co=
urier" class=3D"">while ( (stream &gt;&gt; std::ws).good() &amp;&amp; strea=
m &gt;&gt; n ) use( n );</font></div></div><div class=3D""><br class=3D""><=
/div><div class=3D"">This loop will exit upon EOF, with <font face=3D"Couri=
er" class=3D"">stream =3D=3D true</font>, or failure, with <font face=3D"Co=
urier" class=3D"">stream =3D=3D false</font>.</div><div class=3D""><br clas=
s=3D""></div><div class=3D"">Or, how about not using iostreams where tolera=
nce and precise distinctions are needed ;P .</div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_E3EF2884-B04D-44AE-984E-F9016B19F703--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 26 Feb 2015 01:13:38 -0800 (PST)
Raw View
------=_Part_5431_797708807.1424942018434
Content-Type: multipart/alternative;
 boundary="----=_Part_5432_351511028.1424942018434"

------=_Part_5432_351511028.1424942018434
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le jeudi 26 f=C3=A9vrier 2015 10:06:45 UTC+1, David Krauss a =C3=A9crit :
>
> How about:
>

> while ( (stream >> std::ws).good() && stream >> n ) use( n );
>
> This loop will exit upon EOF, with stream =3D=3D true, or failure, with s=
tream=20
> =3D=3D false.
>
> Or, how about not using iostreams where tolerance and precise distinction=
s=20
> are needed ;P .
>
=20
We agree for sure on that.

--=20
Jean-Marc

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_5432_351511028.1424942018434
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le jeudi 26 f=C3=A9vrier 2015 10:06:45 UTC+1, David Krauss=
 a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=
=3D"word-wrap:break-word">How about:<br></div></blockquote><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><div>=
<br></div><div><font face=3D"Courier">while ( (stream &gt;&gt; std::ws).goo=
d() &amp;&amp; stream &gt;&gt; n ) use( n );</font></div></div><div><br></d=
iv><div>This loop will exit upon EOF, with <font face=3D"Courier">stream =
=3D=3D true</font>, or failure, with <font face=3D"Courier">stream =3D=3D f=
alse</font>.</div><div><br></div><div>Or, how about not using iostreams whe=
re tolerance and precise distinctions are needed ;P .</div></div></blockquo=
te><div>&nbsp;</div><div>We agree for sure on that.</div><div><br></div><di=
v>--&nbsp;</div><div>Jean-Marc</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5432_351511028.1424942018434--
------=_Part_5431_797708807.1424942018434--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 17:16:41 +0800
Raw View
--Apple-Mail=_A3D262B8-3121-4285-B770-F324E6A14755
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 5:04 PM, Nevin Liber <nevin@eviloverlor=
d.com> wrote:
>=20
> It is a truly horrible idea to encourage people to use exceptions in libr=
aries that are likely to be called from destructors.

What are you saying? Not to use iostreams from destructors? Not to throw ex=
ceptions on failure conditions?

In custom stream inserters and extractors, just use stream.clear(std::ios::=
failbit), which throws according to user preferences. I=E2=80=99m not sugge=
sting for users to invent or throw their own iostreams exceptions. Extensib=
ility within ios::failure would be nice though.

> Wrapping everything in a destructor in a try..catch block is a usability =
nightmare.  And making error handling inconsistent input vs. output for the=
 same library (it is supposed to be one combined library) would be a strict=
ly worse choice.

It=E2=80=99s not a library-wide decision. You choose which streams throw an=
d which don=E2=80=99t.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_A3D262B8-3121-4285-B770-F324E6A14755
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 5:04 PM, Nevin Liber &lt;<a href=3D"mailto:nevin@eviloverlo=
rd.com" class=3D"">nevin@eviloverlord.com</a>&gt; wrote:</div><div class=3D=
""><div dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=3D"gma=
il_quote"><div class=3D""><br class=3D""></div><div class=3D"">It is a trul=
y horrible idea to encourage people to use exceptions in libraries that are=
 likely to be called from destructors.</div></div></div></div></div></block=
quote><div><br class=3D""></div><div>What are you saying? Not to use iostre=
ams from destructors? Not to throw exceptions on failure conditions?</div><=
div><br class=3D""></div><div>In custom stream inserters and extractors, ju=
st use <font face=3D"Courier" class=3D"">stream.clear(std::ios::failbit)</f=
ont>, which throws according to user preferences. I=E2=80=99m not suggestin=
g for users to invent or throw their own iostreams exceptions. Extensibilit=
y within <font face=3D"Courier" class=3D"">ios::failure</font> would be nic=
e though.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div cla=
ss=3D""><div dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div class=3D"">Wrapping everything in a destructor in a t=
ry..catch block is a usability nightmare.&nbsp; And making error handling <=
i class=3D"">inconsistent</i>&nbsp;input vs. output for the <i class=3D"">s=
ame</i> library (it is supposed to be one combined library) would be a stri=
ctly worse choice.</div></div></div></div></div></blockquote><div><br class=
=3D""></div><div>It=E2=80=99s not a library-wide decision. You choose which=
 streams throw and which don=E2=80=99t.</div></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_A3D262B8-3121-4285-B770-F324E6A14755--

.


Author: anthonypon@gmail.com
Date: Thu, 26 Feb 2015 01:31:48 -0800 (PST)
Raw View
------=_Part_2818_997462628.1424943108171
Content-Type: multipart/alternative;
 boundary="----=_Part_2819_1097040314.1424943108171"

------=_Part_2819_1097040314.1424943108171
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Thursday, February 26, 2015 at 5:28:59 PM UTC+9, Jean-Marc Bourguet=20
wrote:
>
> Le jeudi 26 f=C3=A9vrier 2015 08:26:19 UTC+1, antho...@gmail.com a =C3=A9=
crit :
>>
>>
>>
>> On Thursday, February 26, 2015 at 2:18:13 PM UTC+9, David Krauss wrote:
>>>
>>>
>>> On 2015=E2=80=9302=E2=80=9326, at 12:29 PM, antho...@gmail.com wrote:
>>>
>>> Hello,
>>>
>>> This is a "*Float the idea" *post per the=20
>>> https://isocpp.org/std/submit-a-proposal steps, though my idea may=20
>>> break old code so I'm currently just seeking to see if I'm missing=20
>>> something, there's some existing proposal in this space, interest level=
s,=20
>>> and hopefully a better idea!
>>>
>>> The task: read numbers from a stream, print error message if there's ba=
d=20
>>> input
>>>
>>> Commonly recommended approach:
>>>
>>>     int n;
>>>     while (stream >> n)
>>>         ;
>>>     if (!stream && !stream.eof())
>>>         std::cerr << "choked on bad input\n=E2=80=9D;
>>>
>>>
>>> By whom? The most common recommendation I recall on this topic is, =E2=
=80=9C
>>> eof() probably isn=E2=80=99t what you want.=E2=80=9D
>>>
>>> To check for a failure due to bad input or parsing, use fail(). (And to=
=20
>>> check for an I/O error, use bad().) To check that the stream is emptied=
=20
>>> without error in general, use rdstate() =3D=3D std::ios::eofbit.
>>>
>> =20
>> The point is that fail() is set after stream >> n hits eof, without ther=
e=20
>> being "bad"/un-parsable input.
>>
>
> You tried to input something, that input failed.  There is indeed no=20
> difference between failing due to missing data and bad data with >> if yo=
u=20
> automatically skip over the whitespace. If you want to do so, you'll have=
=20
> to skip the white space manually (and disable the possibility to skip=20
> automatically, ws is using the sentry which set the error)
>
>     stream >> std::noskipws;
>     while (stream >> std::ws && !stream.eof() && stream >> n) {
>         std::cout << "got " << n << '\n';
>     }
>     if (stream.bad()) std::cout << "IO error\n";
>     if (stream.fail()) std::cout << "Bad format\n";
>

It's the need for such code that precipitated my post.  I don't think C++=
=20
newbies should be expected to write such code in order to do something as=
=20
simple as parse numbers from a stream robustly.
=20

> Usually, the distinction doesn't worth the pain (maybe because I share=20
> with the IOStream designers an Unix bias, Unix considers `\n` as line=20
> terminator so non terminated last lines are oddities which can be ignored=
=20
> when IOStream formatted input is an adequate mechanism).
>

Same background here, but if istreams were necessarily files (and everyone=
=20
used sane editors) it would be less of a concern, but std::istringstreams=
=20
initialised from string literals, network input etc. are quite likely not=
=20
to be whitespace terminated.
=20

> When I use formatted IOstream input, I use this kind of loop:
>
>     while (stream >> n) {
>         std::cout << "got " << n << '\n';
>     }
>     if (stream.bad()) std::cout << "IO error\n";
>     if (!stream.eof()) std::cout << "Bad format\n";
>

Yup - I've tended to settle for that too - would be nice if it handled this=
=20
"bad input at end" corner-case.
=20

> Failing case: stream contains say "-", at least on the GCC compiler at=20
>>> ideone.com the stream >> n operation sets *both *failbit and eofbit, as=
=20
>>> '-' is consumed as a potentially valid part of a number that never=20
>>> materialises.
>>>
>>>
>>> Unless you recognize the failure *and* seek the stream back before the=
=20
>>> dash (or somehow unget it), the condition is irrecoverable.
>>>
>>
>> Exactly.  My point is: isn't that undesirable?  Shouldn't the library=20
>> make it easy to see why the loop terminated?
>>
>
> If you go to the point where error recovery is needed, IOStream formatted=
=20
> input is probably no more an adequate solution.
>

Currently yes, but could a proposal like this help rectify the situation?
=20

>
>>> Try this:
>>>
>>> while (stream) { stream >> n; use(n); }
>>>
>>
> That's wrong: never use the result of an IO operation without being sure=
=20
> that the IO operation succeeded.
>
> Yours,
>
> --=20
> Jean-Marc
>

Cheers,
Tony=20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_2819_1097040314.1424943108171
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 5:28:59 PM UTC+9=
, Jean-Marc Bourguet wrote:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">Le jeudi 26 f=C3=A9vrier 2015 08:26:19 UTC+1, <a>antho...@gma=
il.com</a> a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 2:18:13 PM UTC+9, Dav=
id Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-=
wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=E2=80=9302=
=E2=80=9326, at 12:29 PM, <a rel=3D"nofollow">antho...@gmail.com</a> wrote:=
</div><br><div><div dir=3D"ltr">Hello,<br><br>This is a "<b>Float&nbsp;the =
idea" </b>post per the <a href=3D"https://isocpp.org/std/submit-a-proposal"=
 rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://www=
..google.com/url?q\75https%3A%2F%2Fisocpp.org%2Fstd%2Fsubmit-a-proposal\46sa=
\75D\46sntz\0751\46usg\75AFQjCNGlLyCIYYQUZNTTJdUEpCYxvwG8Ig';return true;" =
onclick=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fisocpp=
..org%2Fstd%2Fsubmit-a-proposal\46sa\75D\46sntz\0751\46usg\75AFQjCNGlLyCIYYQ=
UZNTTJdUEpCYxvwG8Ig';return true;">https://isocpp.org/std/submit-<wbr>a-pro=
posal</a> steps, though my idea may break old code so I'm currently just se=
eking to see if I'm missing something, there's some existing proposal in th=
is space, interest levels, and hopefully a better idea!<br><br>The task: re=
ad numbers from a stream, print error message if there's bad input<br><br>C=
ommonly recommended approach:<br><br>&nbsp; &nbsp; int n;<br>&nbsp;&nbsp;&n=
bsp; while (stream &gt;&gt; n)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
; ;<br>&nbsp;&nbsp;&nbsp; if (!stream &amp;&amp; !stream.eof())<br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cerr &lt;&lt; "choked on bad input\=
n=E2=80=9D;<br></div></div></blockquote><div><br></div><div>By whom? The mo=
st common recommendation I recall on this topic is, =E2=80=9C<font face=3D"=
Courier">eof()</font> probably isn=E2=80=99t what you want.=E2=80=9D</div><=
div><br></div><div>To check for a failure due to bad input or parsing, use =
<font face=3D"Courier">fail()</font>. (And to check for an I/O error, use <=
font face=3D"Courier">bad()</font>.) To check that the stream is emptied wi=
thout error in general, use <font face=3D"Courier">rdstate() =3D=3D std::io=
s::eofbit</font>.</div></div></div></blockquote><div>&nbsp;</div><div>The p=
oint is that fail() is set after stream &gt;&gt; n hits eof, without there =
being "bad"/un-parsable input.<br></div></div></blockquote><div><br></div><=
div>You tried to input something, that input failed. &nbsp;There is indeed =
no difference between failing due to missing data and bad data with &gt;&gt=
; if you automatically skip over the whitespace. If you want to do so, you'=
ll have to skip the white space manually (and disable the possibility to sk=
ip automatically, ws is using the sentry which set the error)</div><div><br=
></div><div>&nbsp; &nbsp; stream &gt;&gt; std::noskipws;</div><div>&nbsp; &=
nbsp; while (stream &gt;&gt; std::ws &amp;&amp; !stream.eof() &amp;&amp; st=
ream &gt;&gt; n) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; std::cout &lt;&lt;=
 "got " &lt;&lt; n &lt;&lt; '\n';</div><div>&nbsp; &nbsp; }</div><div>&nbsp=
; &nbsp; if (stream.bad()) std::cout &lt;&lt; "IO error\n";</div><div>&nbsp=
; &nbsp; if (stream.fail()) std::cout &lt;&lt; "Bad format\n";</div></div><=
/blockquote><div><br>It's the need for such code that precipitated my post.=
&nbsp; I don't think C++ newbies should be expected to write such code in o=
rder to do something as simple as parse numbers from a stream robustly.<br>=
&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div>Usually, the distinction doesn't worth the pain (maybe because I share =
with the IOStream designers an Unix bias, Unix considers `\n` as line termi=
nator so non terminated last lines are oddities which can be ignored when I=
OStream formatted input is an adequate mechanism).</div></div></blockquote>=
<div><br>Same background here, but if istreams were necessarily files (and =
everyone used sane editors) it would be less of a concern, but std::istring=
streams initialised from string literals, network input etc. are quite like=
ly not to be whitespace terminated.<br>&nbsp;</div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div dir=3D"ltr"><div> When I use formatted IOstream i=
nput, I use this kind of loop:</div><div><div><br></div><div>&nbsp; &nbsp; =
while (stream &gt;&gt; n) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; std::cout=
 &lt;&lt; "got " &lt;&lt; n &lt;&lt; '\n';</div><div>&nbsp; &nbsp; }</div><=
div>&nbsp; &nbsp; if (stream.bad()) std::cout &lt;&lt; "IO error\n";</div><=
div>&nbsp; &nbsp; if (!stream.eof()) std::cout &lt;&lt; "Bad format\n";</di=
v></div></div></blockquote><div><br>Yup - I've tended to settle for that to=
o - would be nice if it handled this "bad input at end" corner-case.<br>&nb=
sp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div style=3D"word-wrap:break-word"><div><blockquote type=
=3D"cite"><div><div dir=3D"ltr">Failing case: stream contains say "-", at l=
east on the GCC compiler at <a href=3D"http://ideone.com" rel=3D"nofollow" =
target=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fideone.com\46sa\75D\46sntz\0751\46usg\75AFQjCNEgkElpZvlncw_m4=
nl7yXNHs2t0xA';return true;" onclick=3D"this.href=3D'http://www.google.com/=
url?q\75http%3A%2F%2Fideone.com\46sa\75D\46sntz\0751\46usg\75AFQjCNEgkElpZv=
lncw_m4nl7yXNHs2t0xA';return true;">ideone.com</a> the stream &gt;&gt; n op=
eration sets <i>both </i>failbit and eofbit, as '-' is consumed as a potent=
ially valid part of a number that never materialises.<br></div></div></bloc=
kquote><div><br></div>Unless you recognize the failure&nbsp;<i>and</i>&nbsp=
;seek the stream back before the dash (or somehow unget it), the condition =
is irrecoverable.<br></div></div></blockquote><div><br>Exactly.&nbsp; My po=
int is: isn't that undesirable?&nbsp; Shouldn't the library make it easy to=
 see why the loop terminated?<br></div></div></blockquote><div><br></div><d=
iv>If you go to the point where error recovery is needed, IOStream formatte=
d input is probably no more an adequate solution.</div></div></blockquote><=
div><br>Currently yes, but could a proposal like this help rectify the situ=
ation?<br>&nbsp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
 dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div=
><br></div>Try this:<div><br></div><div><font face=3D"Courier">while (strea=
m) { stream &gt;&gt; n; use(n); }<br></font></div></div></blockquote></div>=
</blockquote><div><br></div><div>That's wrong: never use the result of an I=
O operation without being sure that the IO operation succeeded.</div><div><=
br></div><div>Yours,</div><div><br></div><div>--&nbsp;</div><div>Jean-Marc<=
/div></div></blockquote><div><br>Cheers,<br>Tony <br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2819_1097040314.1424943108171--
------=_Part_2818_997462628.1424943108171--

.


Author: anthonypon@gmail.com
Date: Thu, 26 Feb 2015 01:44:13 -0800 (PST)
Raw View
------=_Part_2301_1510290486.1424943853745
Content-Type: multipart/alternative;
 boundary="----=_Part_2302_195490662.1424943853745"

------=_Part_2302_195490662.1424943853745
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Thursday, February 26, 2015 at 5:19:29 PM UTC+9, David Krauss wrote:
>
>
> On 2015=E2=80=9302=E2=80=9326, at 3:26 PM, antho...@gmail.com <javascript=
:> wrote:
>
> The point is that fail() is set after stream >> n hits eof, without there=
=20
> being "bad"/un-parsable input.
>
>
> There was bad input, the dash character. And your proposal is that eofbit=
=20
> sometimes not be set at the EOF, not that failbit not be set after a=20
> conversion failure.
>

What I mean by [[ "The point is that fail() is set after stream >> n hits=
=20
eof, without there being "bad"/un-parsable input." ]] is that even when=20
there's a simple eof condition (no longer talking about a hyphen), finding=
=20
it while attempting stream >> n sets both failbit and eofbit... after >>=20
it's too late to differentiate.
=20

> If you=E2=80=99re concerned with conversion failures and not with eof, ch=
eck=20
> failbit/fail() and not eofbit/eof().
>

We seem to be going round in circles.  As above, that doesn't work because=
=20
both bits are set for both an eof and a bad-input condition, given a loop=
=20
controlled by stream >> n.

> In a loop, checking eof() is especially not to be encouraged.
>>
>
>  Agreed - it's in desperation that coders are forced back to this ugly an=
d=20
> error-prone mess.  Hence my original post.
>
>
> There are right answers, albeit buried among wrong answers. That=E2=80=99=
s the way=20
> iostreams is, but this proposal seems to be shaking things up without=20
> making correct code easier overall.
>

How is changing standard behaviour to make the following "work" as might be=
=20
naively expected *not* easier overall?

    while (stream >> n)
          ;
    if (stream.fail() && !stream.eof())
        ...report bad input...
=20

> Again, though, eof() is seldom the right solution.
>

I'm not suggesting eof() be used... my proposal is to remove the need to=20
use it to handle this situation.=20

> The robustness improvement comes from differentiating a stream of good=20
> input from a stream terminated by bad (likely truncated in the case of "-=
")=20
> input.  It's not about being able to get other input from the stream=20
> afterwards; rather, one might print an error and terminate until the user=
=20
> fixes the input instead of presenting results calculated from=20
> bogus/incomplete input.
>
>
> Streams with bad input are differentiated by failbit. Period.
>

Again, the problem is failbit also happens when you try a final stream >> n=
=20
when there's nothing (but possibly whitespace) left in the stream.=20

>     while (!stream.eof()) { stream >> n; use(n); }
>>
>>
>> This is exactly what you should never do.
>>
>
> That's not a particularly useful perspective.  I've presented it only to=
=20
> illustrate currently working (but extremely fragile) code that would be=
=20
> broken by this proposal.  Sure we can deride anyone silly enough to write=
=20
> code like this (I certainly would in a code review), but it's still=20
> important for me to acknowledge and illustrate how the proposal is a=20
> breaking change.
>
>
> Okay, but it looks similar to your first example, in that eof is being=20
> used as a proxy for something else.
>
> In this case, any conversion error leads to an infinite loop, which is=20
> extra bad.
>

It's hideous, but if the programmer trusts their inputs (e.g. they've=20
generated them elsewhere in the program), they may not care.  I'd still be=
=20
breaking working core irrespective of how misguided writing that code was.

> Tried here: http://ideone.com/BpKisk=20
> <http://www.google.com/url?q=3Dhttp%3A%2F%2Fideone.com%2FBpKisk&sa=3DD&sn=
tz=3D1&usg=3DAFQjCNHiB2XjREMVYMpgYzgRRhT8iGp4SA>
> =20
>
> Result: no warning for istringstream("2 3 -=E2=80=9C);
>
>
> The warning is printed there on the webpage under =E2=80=9Cstderr.=E2=80=
=9D
>

Oh yup - sorry - every month or three that website throws me doing that. =
=20
Again, the problem is that the same message is reported for an end-of-file=
=20
condition - as demonstrated at http://ideone.com/E1ajY6

> Or more safely and lazily:
>>
>> stream.exceptions( std::ios::failbit | std::ios::badbit );
>> while (stream) { stream >> n; use(n); }
>>
> =20
> That doesn't seem to work either - same terminating stream state for "3 4=
=20
> -" and "3 4" - see http://ideone.com/UYKQiS
>
>
> Ah, I forgot that converting the stream to bool only tests failbit, not=
=20
> eofbit. Also, you need to manually eat the trailing space if it=E2=80=99s=
 going to=20
> make a difference to the loop condition.
>
> This is correct:
>
> stream.exceptions( std::ios::failbit | std::ios::badbit );
> while (stream.good()) { stream >> n >> std::ws; use(n); }
>
> Yes, iostreams is finicky=E2=80=A6
>

Agreed, so - can it be less so with minimal changes - like those proposed?=
=20

> Perhaps more folks would use automatic stream exceptions if they were mor=
e=20
>> friendly. Here are some ideas:
>>
>> 1. Specify or recommend better default error messages for uncaught=20
>> ios_base::failure exceptions.
>> 2. Add a hook to ios_base::failure to add a user-visible file or stream=
=20
>> name, let the standard streams initialize it in an unspecified way.
>> 3. Create a sentry guard so you can set exceptions() at the beginning of=
=20
>> a try block, and have it restored when it exits.
>>
>
> Who could argue with better error messages?  Scope guards sound good too =
-=20
> but easily implemented outside the Standard.  For 2 - if the exception's=
=20
> caught in the scope containing the stream then it's not necessary, and if=
=20
> not the stream's already destroyed.
>
>
> #2 is more useful for proper I/O, not stringstreams. It can help a progra=
m=20
> generate a somewhat sensible error message for the user: =E2=80=9CExpecte=
d a=20
> number, got =E2=80=98z=E2=80=99 in HTTP POST input=E2=80=9D.
>
> Point is, if the what() strings were more sensible, there would be less=
=20
> need to process the exceptions at all. Either generically catch after=20
> aborting and print exc.what(), or don=E2=80=99t catch and let the program=
=20
> terminate, still getting a reasonable diagnostic log entry.
>

Definitely in favour of whatever anyone can do to get better error=20
messages, though there's the risk of making the exception-throwing stream=
=20
state less performant too... lots to balance out.=20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_2302_195490662.1424943853745
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 5:19:29 PM UTC+9=
, David Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div styl=
e=3D"word-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=
=E2=80=9302=E2=80=9326, at 3:26 PM, <a href=3D"javascript:" target=3D"_blan=
k" gdf-obfuscated-mailto=3D"uTFuxon7sVAJ" rel=3D"nofollow" onmousedown=3D"t=
his.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:'=
;return true;">antho...@gmail.com</a> wrote:</div><br><div><div dir=3D"ltr"=
 style=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-varia=
nt:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-=
align:start;text-indent:0px;text-transform:none;white-space:normal;word-spa=
cing:0px">The point is that fail() is set after stream &gt;&gt; n hits eof,=
 without there being "bad"/un-parsable input.</div></div></blockquote><div>=
<br></div><div>There was bad input, the dash character. And your proposal i=
s that eofbit sometimes not be set at the EOF, not that failbit not be set =
after a conversion failure.</div></div></div></blockquote><div><br>What I m=
ean by [[ "The point is that fail() is set after stream &gt;&gt; n hits eof=
, without there being "bad"/un-parsable input." ]] is that even when there'=
s a simple eof condition (no longer talking about a hyphen), finding it whi=
le attempting stream &gt;&gt; n sets both failbit and eofbit... after &gt;&=
gt; it's too late to differentiate.<br>&nbsp;</div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><div>If you=
=E2=80=99re concerned with conversion failures and not with eof, check fail=
bit/fail() and not eofbit/eof().</div></div></div></blockquote><div><br>We =
seem to be going round in circles.&nbsp; As above, that doesn't work becaus=
e both bits are set for both an eof and a bad-input condition, given a loop=
 controlled by stream &gt;&gt; n.<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"c=
ite"><div dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-st=
yle:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;lin=
e-height:normal;text-align:start;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204=
,204);border-left-style:solid;padding-left:1ex"><div style=3D"word-wrap:bre=
ak-word"><div><div>In a loop, checking&nbsp;<span style=3D"font-family:Cour=
ier">eof()</span>&nbsp;is especially not to be encouraged.</div></div></div=
></blockquote><div><br>&nbsp;Agreed - it's in desperation that coders are f=
orced back to this ugly and error-prone mess.&nbsp; Hence my original post.=
<br></div></div></blockquote><div><br></div><div>There are right answers, a=
lbeit buried among wrong answers. That=E2=80=99s the way iostreams is, but =
this proposal seems to be shaking things up without making correct code eas=
ier overall.</div></div></div></blockquote><div><br>How is changing standar=
d behaviour to make the following "work" as might be naively expected <b>no=
t</b> easier overall?<br><br>&nbsp;&nbsp;&nbsp; while (stream &gt;&gt; n)<b=
r>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;<br>&nbsp;&nbsp;&nbsp; if (stream.fai=
l() &amp;&amp; !stream.eof())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 ...report bad input...<br>&nbsp;</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div style=3D"word-wrap:break-word"><div><div>Again, though, <font=
 face=3D"Courier">eof()</font> is seldom the right solution.</div></div></d=
iv></blockquote><div><br>I'm not suggesting eof() be used... my proposal is=
 to remove the need to use it to handle this situation. <br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><di=
v><blockquote type=3D"cite"><div><div dir=3D"ltr" style=3D"font-family:Helv=
etica;font-size:12px;font-style:normal;font-variant:normal;font-weight:norm=
al;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0p=
x;text-transform:none;white-space:normal;word-spacing:0px"><div>The robustn=
ess improvement comes from differentiating a stream of good input from a st=
ream terminated by bad (likely truncated in the case of "-") input.&nbsp; I=
t's not about being able to get other input from the stream afterwards; rat=
her, one might print an error and terminate until the user fixes the input =
instead of presenting results calculated from bogus/incomplete input.<br></=
div></div></div></blockquote><div><br></div><div>Streams with bad input are=
 differentiated by <font face=3D"Courier">failbit</font>. Period.</div></di=
v></div></blockquote><div><br>Again, the problem is failbit also happens wh=
en you try a final stream &gt;&gt; n when there's nothing (but possibly whi=
tespace) left in the stream. <br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite"=
><div dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-style:=
normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-he=
ight:normal;text-align:start;text-indent:0px;text-transform:none;white-spac=
e:normal;word-spacing:0px"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204=
);border-left-style:solid;padding-left:1ex"><div style=3D"word-wrap:break-w=
ord"><div><blockquote type=3D"cite"><div><div dir=3D"ltr">&nbsp; &nbsp; whi=
le (!stream.eof()) { stream &gt;&gt; n; use(n); }<br></div></div></blockquo=
te><div><br></div>This is exactly what you should never do.<br></div></div>=
</blockquote><div><br>That's not a particularly useful perspective.&nbsp; I=
've presented it only to illustrate currently working (but extremely fragil=
e) code that would be broken by this proposal.&nbsp; Sure we can deride any=
one silly enough to write code like this (I certainly would in a code revie=
w), but it's still important for me to acknowledge and illustrate how the p=
roposal is a breaking change.<br></div></div></blockquote><div><br></div><d=
iv>Okay, but it looks similar to your first example, in that eof is being u=
sed as a proxy for something else.</div><div><br></div><div>In this case, a=
ny conversion error leads to an infinite loop, which is extra bad.</div></d=
iv></div></blockquote><div><br>It's hideous, but if the programmer trusts t=
heir inputs (e.g. they've generated them elsewhere in the program), they ma=
y not care.&nbsp; I'd still be breaking working core irrespective of how mi=
sguided writing that code was.<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite=
"><div><div dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-=
style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;l=
ine-height:normal;text-align:start;text-indent:0px;text-transform:none;whit=
e-space:normal;word-spacing:0px"><div>Tried here:<span>&nbsp;</span><a href=
=3D"http://www.google.com/url?q=3Dhttp%3A%2F%2Fideone.com%2FBpKisk&amp;sa=
=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNHiB2XjREMVYMpgYzgRRhT8iGp4SA" target=3D"_=
blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.com/u=
rl?q\75http%3A%2F%2Fideone.com%2FBpKisk\46sa\75D\46sntz\0751\46usg\75AFQjCN=
HiB2XjREMVYMpgYzgRRhT8iGp4SA';return true;" onclick=3D"this.href=3D'http://=
www.google.com/url?q\75http%3A%2F%2Fideone.com%2FBpKisk\46sa\75D\46sntz\075=
1\46usg\75AFQjCNHiB2XjREMVYMpgYzgRRhT8iGp4SA';return true;">http://ideone.c=
om/BpKisk</a><span><wbr>&nbsp;</span><br><br>Result: no warning for istring=
stream("2 3 -=E2=80=9C);<br></div></div></div></blockquote><div><br></div><=
div>The warning is printed there on the webpage under =E2=80=9Cstderr.=E2=
=80=9D</div></div></div></blockquote><div><br>Oh yup - sorry - every month =
or three that website throws me doing that.&nbsp; Again, the problem is tha=
t the same message is reported for an end-of-file condition - as demonstrat=
ed at http://ideone.com/E1ajY6<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite=
"><div dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-style=
:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-h=
eight:normal;text-align:start;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,20=
4);border-left-style:solid;padding-left:1ex"><div style=3D"word-wrap:break-=
word"><div></div><div>Or more safely and lazily:</div><div><br></div><div><=
font face=3D"Courier">stream.exceptions( std::ios::failbit | std::ios::badb=
it );</font></div><div><font face=3D"Courier">while (stream) { stream &gt;&=
gt; n; use(n); }<br></font></div></div></blockquote><div>&nbsp;</div><div>T=
hat doesn't seem to work either - same terminating stream state for "3 4 -"=
 and "3 4" - see<span>&nbsp;</span><a href=3D"http://ideone.com/UYKQiS" tar=
get=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.goog=
le.com/url?q\75http%3A%2F%2Fideone.com%2FUYKQiS\46sa\75D\46sntz\0751\46usg\=
75AFQjCNGHk40pRuuVzBsSxXiFUKofmEM9Mw';return true;" onclick=3D"this.href=3D=
'http://www.google.com/url?q\75http%3A%2F%2Fideone.com%2FUYKQiS\46sa\75D\46=
sntz\0751\46usg\75AFQjCNGHk40pRuuVzBsSxXiFUKofmEM9Mw';return true;">http://=
ideone.com/UYKQiS</a><br></div></div></blockquote><div><br></div><div>Ah, I=
 forgot that converting the stream to bool only tests failbit, not eofbit. =
Also, you need to manually eat the trailing space if it=E2=80=99s going to =
make a difference to the loop condition.</div><div><br></div><div>This is c=
orrect:</div><div><br></div><div><font face=3D"Courier">stream.exceptions( =
std::ios::failbit | std::ios::badbit );</font></div><div><font face=3D"Cour=
ier">while (stream.good()) { stream &gt;&gt; n &gt;&gt; std::ws; use(n); }<=
br></font><br></div><div>Yes, iostreams is finicky=E2=80=A6</div></div></di=
v></blockquote><div><br>Agreed, so - can it be less so with minimal changes=
 - like those proposed? <br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite"><d=
iv dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-style:nor=
mal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-heigh=
t:normal;text-align:start;text-indent:0px;text-transform:none;white-space:n=
ormal;word-spacing:0px"><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);b=
order-left-style:solid;padding-left:1ex"><div style=3D"word-wrap:break-word=
"><div></div><div>Perhaps more folks would use automatic stream exceptions =
if they were more friendly. Here are some ideas:</div><div><br></div><div>1=
.. Specify or recommend better default error messages for uncaught&nbsp;<spa=
n style=3D"font-family:Courier">ios_base::failure</span>&nbsp;<wbr>exceptio=
ns.</div><div>2. Add a hook to<span>&nbsp;</span><font face=3D"Courier">ios=
_base::failure</font>&nbsp;to add a user-visible file or stream name, let t=
he standard streams initialize it in an unspecified way.</div><div>3. Creat=
e a sentry guard so you can set<span>&nbsp;</span><font face=3D"Courier">ex=
ceptions()</font><span>&nbsp;</span>at the beginning of a try block, and ha=
ve it restored when it exits.</div></div></blockquote><div><br>Who could ar=
gue with better error messages?&nbsp; Scope guards sound good too - but eas=
ily implemented outside the Standard.&nbsp; For 2 - if the exception's caug=
ht in the scope containing the stream then it's not necessary, and if not t=
he stream's already destroyed.<br></div></div></blockquote><div><br></div><=
div>#2 is more useful for proper I/O, not stringstreams. It can help a prog=
ram generate a somewhat sensible error message for the user: =E2=80=9CExpec=
ted a number, got =E2=80=98z=E2=80=99 in HTTP POST input=E2=80=9D.</div><di=
v><br></div><div>Point is, if the what() strings were more sensible, there =
would be less need to process the exceptions at all. Either generically cat=
ch after aborting and print exc.what(), or don=E2=80=99t catch and let the =
program terminate, still getting a reasonable diagnostic log entry.</div></=
div></div></blockquote><div><br>Definitely in favour of whatever anyone can=
 do to get better error messages, though there's the risk of making the exc=
eption-throwing stream state less performant too... lots to balance out. <b=
r></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2302_195490662.1424943853745--
------=_Part_2301_1510290486.1424943853745--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Feb 2015 18:34:12 +0800
Raw View
--Apple-Mail=_E20AD675-4871-46F9-85BF-35B12FFA73B9
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9326, at 5:44 PM, anthonypon@gmail.com wrote:
>=20
>=20
>=20
> On Thursday, February 26, 2015 at 5:19:29 PM UTC+9, David Krauss wrote:
>=20
>> On 2015=E2=80=9302=E2=80=9326, at 3:26 PM, antho...@ <>gmail.com <http:/=
/gmail.com/> wrote:
>>=20
>> The point is that fail() is set after stream >> n hits eof, without ther=
e being "bad"/un-parsable input.
>=20
> There was bad input, the dash character. And your proposal is that eofbit=
 sometimes not be set at the EOF, not that failbit not be set after a conve=
rsion failure.
>=20
> What I mean by [[ "The point is that fail() is set after stream >> n hits=
 eof, without there being "bad"/un-parsable input." ]] is that even when th=
ere's a simple eof condition (no longer talking about a hyphen), finding it=
 while attempting stream >> n sets both failbit and eofbit... after >> it's=
 too late to differentiate.

It sets failbit because n remains uninitialized. It sets eofbit because the=
 stream is at eof.

You=E2=80=99re essentially trying to specialize stream >> n for loop condit=
ions. Although the proposal =E2=80=9Cfixes=E2=80=9D the given case, the sem=
antics become inconsistent and confusing for other cases. Usually eof is se=
t whenever the end of the stream is touched. If exceptions(std::ios::eofbit=
) is set, then the extractor might even lose control before observing the e=
of condition. Do you propose that be worked around?

The solution is to use a more sophisticated loop.

> I'm not suggesting eof() be used... my proposal is to remove the need to =
use it to handle this situation.=20

Your proposal is that eof shouldn=E2=80=99t be set when failbit is set, whe=
n the extractor already extracted a non-whitespace character. Given that, e=
of still needs to be called to differentiate failure due to no input at all=
 (the =E2=80=9C3 4=E2=80=9D case, where you still expect eof to be set), fr=
om failure due to unexpected input at the end (the =E2=80=9C3 4 -=E2=80=9D =
case, where the state of eof is surprising to you).

> Streams with bad input are differentiated by failbit. Period.
>=20
> Again, the problem is failbit also happens when you try a final stream >>=
 n when there's nothing (but possibly whitespace) left in the stream.=20

There=E2=80=99s no way that failbit won=E2=80=99t be set by that operation:=
 n remains uninitialized, so it=E2=80=99s a failure due to bad input.

The grammar expressed by while ( stream >> n ) is impossible to satisfy in =
finite time. If there=E2=80=99s no other exit condition, it must end in fai=
lure.

You can try making your proposal. I=E2=80=99m only one person here, and not=
 a committee member. But my sensibility would be to fix the grammar and the=
 loop, not the library. =E2=80=9CMost users=E2=80=9D just want to avoid end=
less loops and UB, so your use case doesn=E2=80=99t sound as representative=
 as it=E2=80=99s presented to be.

> Definitely in favour of whatever anyone can do to get better error messag=
es, though there's the risk of making the exception-throwing stream state l=
ess performant too... lots to balance out.=20

The best way to optimize the unexceptional state is to throw exceptions and=
 not waste time testing error flags. As for iostreams, it does the error fl=
ag checks whether you enable exceptions or not, so it=E2=80=99s permanently=
 pessimized.

I don=E2=80=99t want to suggest anything to make any streams more heavyweig=
ht, and some Unix fstream implementations indeed can=E2=80=99t recover a fi=
lename from an open stream. On the other hand, some (Linux at least) can, a=
t least to an approximation that would be sufficient for an error message. =
In any case, hopefully a hook could be added without too much ABI disturban=
ce. After all, error codes were just recently added.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_E20AD675-4871-46F9-85BF-35B12FFA73B9
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9326, at 5:44 PM, <a href=3D"mailto:anthonypon@gmail.com" class=3D""=
>anthonypon@gmail.com</a> wrote:</div><br class=3D"Apple-interchange-newlin=
e"><div class=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; font-s=
ize: 12px; font-style: normal; font-variant: normal; font-weight: normal; l=
etter-spacing: normal; line-height: normal; orphans: auto; text-align: star=
t; text-indent: 0px; text-transform: none; white-space: normal; widows: aut=
o; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><br class=
=3D""><br class=3D"">On Thursday, February 26, 2015 at 5:19:29 PM UTC+9, Da=
vid Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); =
border-left-style: solid; padding-left: 1ex;"><div style=3D"word-wrap: brea=
k-word;" class=3D""><br class=3D""><div class=3D""><blockquote type=3D"cite=
" class=3D""><div class=3D"">On 2015=E2=80=9302=E2=80=9326, at 3:26 PM,<spa=
n class=3D"Apple-converted-space">&nbsp;</span><a target=3D"_blank" gdf-obf=
uscated-mailto=3D"uTFuxon7sVAJ" rel=3D"nofollow" class=3D"">antho...@</a><a=
 href=3D"http://gmail.com/" class=3D"">gmail.com</a><span class=3D"Apple-co=
nverted-space">&nbsp;</span>wrote:</div><br class=3D""><div class=3D""><div=
 dir=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; font-style: =
normal; font-variant: normal; font-weight: normal; letter-spacing: normal; =
line-height: normal; text-align: start; text-indent: 0px; text-transform: n=
one; white-space: normal; word-spacing: 0px;" class=3D"">The point is that =
fail() is set after stream &gt;&gt; n hits eof, without there being "bad"/u=
n-parsable input.</div></div></blockquote><div class=3D""><br class=3D""></=
div><div class=3D"">There was bad input, the dash character. And your propo=
sal is that eofbit sometimes not be set at the EOF, not that failbit not be=
 set after a conversion failure.</div></div></div></blockquote><div class=
=3D""><br class=3D"">What I mean by [[ "The point is that fail() is set aft=
er stream &gt;&gt; n hits eof, without there being "bad"/un-parsable input.=
" ]] is that even when there's a simple eof condition (no longer talking ab=
out a hyphen), finding it while attempting stream &gt;&gt; n sets both fail=
bit and eofbit... after &gt;&gt; it's too late to differentiate.<br class=
=3D""></div></div></div></blockquote><div><br class=3D""></div><div>It sets=
 failbit because n remains uninitialized. It sets eofbit because the stream=
 is at eof.</div><div><br class=3D""></div><div>You=E2=80=99re essentially =
trying to specialize&nbsp;<font face=3D"Courier" class=3D"">stream &gt;&gt;=
 n</font> for loop conditions. Although the proposal =E2=80=9Cfixes=E2=80=
=9D the given case, the semantics become inconsistent and confusing for oth=
er cases. Usually eof is set whenever the end of the stream is touched. If =
<font face=3D"Courier" class=3D"">exceptions(std::ios::eofbit)</font> is se=
t, then the extractor might even lose control before observing the eof cond=
ition. Do you propose that be worked around?</div><div><br class=3D""></div=
><div>The solution is to use a more sophisticated loop.</div><br class=3D""=
><blockquote type=3D"cite" class=3D""><div dir=3D"ltr" style=3D"font-family=
: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; fon=
t-weight: normal; letter-spacing: normal; line-height: normal; orphans: aut=
o; text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" c=
lass=3D""><div class=3D"">I'm not suggesting eof() be used... my proposal i=
s to remove the need to use it to handle this situation.<span class=3D"Appl=
e-converted-space">&nbsp;</span><br class=3D""></div></div></blockquote><di=
v><br class=3D""></div><div>Your proposal is that eof shouldn=E2=80=99t be =
set when failbit is set, when the extractor already extracted a non-whitesp=
ace character. Given that, eof still needs to be called to differentiate fa=
ilure due to no input at all (the =E2=80=9C3 4=E2=80=9D case, where you sti=
ll expect eof to be set), from failure due to unexpected input at the end (=
the =E2=80=9C3 4 -=E2=80=9D case, where the state of eof is surprising to y=
ou).</div><br class=3D""><blockquote type=3D"cite" class=3D""><div dir=3D"l=
tr" style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; f=
ont-variant: normal; font-weight: normal; letter-spacing: normal; line-heig=
ht: normal; orphans: auto; text-align: start; text-indent: 0px; text-transf=
orm: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-te=
xt-stroke-width: 0px;" class=3D""><blockquote class=3D"gmail_quote" style=
=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: r=
gb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style=
=3D"word-wrap: break-word;" class=3D""><div class=3D""><div class=3D"">Stre=
ams with bad input are differentiated by<span class=3D"Apple-converted-spac=
e">&nbsp;</span><font face=3D"Courier" class=3D"">failbit</font>. Period.</=
div></div></div></blockquote><div class=3D""><br class=3D"">Again, the prob=
lem is failbit also happens when you try a final stream &gt;&gt; n when the=
re's nothing (but possibly whitespace) left in the stream.<span class=3D"Ap=
ple-converted-space">&nbsp;</span><br class=3D""></div></div></blockquote><=
div><br class=3D""></div><div>There=E2=80=99s no way that failbit won=E2=80=
=99t be set by that operation: n remains uninitialized, so it=E2=80=99s a f=
ailure due to bad input.</div><div><br class=3D""></div><div>The grammar ex=
pressed by <font face=3D"Courier" class=3D"">while ( stream &gt;&gt; n )</f=
ont> is impossible to satisfy in finite time. If there=E2=80=99s no other e=
xit condition, it&nbsp;<i class=3D"">must</i> end in failure.</div><div><br=
 class=3D""></div><div>You can try making your proposal. I=E2=80=99m only o=
ne person here, and not a committee member. But my sensibility would be to =
fix the grammar and the loop, not the library. =E2=80=9CMost users=E2=80=9D=
 just want to avoid endless loops and UB, so your use case doesn=E2=80=99t =
sound as representative as it=E2=80=99s presented to be.</div><br class=3D"=
"><blockquote type=3D"cite" class=3D""><div dir=3D"ltr" style=3D"font-famil=
y: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; fo=
nt-weight: normal; letter-spacing: normal; line-height: normal; orphans: au=
to; text-align: start; text-indent: 0px; text-transform: none; white-space:=
 normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" =
class=3D""><div class=3D"">Definitely in favour of whatever anyone can do t=
o get better error messages, though there's the risk of making the exceptio=
n-throwing stream state less performant too... lots to balance out.<span cl=
ass=3D"Apple-converted-space">&nbsp;</span><br class=3D""></div></div></blo=
ckquote><div><br class=3D""></div><div>The best way to optimize the unexcep=
tional state is to throw exceptions and not waste time testing error flags.=
 As for iostreams, it does the error flag checks whether you enable excepti=
ons or not, so it=E2=80=99s permanently pessimized.</div><div><br class=3D"=
"></div><div>I don=E2=80=99t want to suggest anything to make any streams m=
ore heavyweight, and some Unix fstream implementations indeed can=E2=80=99t=
 recover a filename from an open stream. On the other hand, some (Linux at =
least) can, at least to an approximation that would be sufficient for an er=
ror message. In any case, hopefully a hook could be added without too much =
ABI disturbance. After all, error codes were just recently added.</div></di=
v></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_E20AD675-4871-46F9-85BF-35B12FFA73B9--

.


Author: anthonypon@gmail.com
Date: Thu, 26 Feb 2015 08:21:40 -0800 (PST)
Raw View
------=_Part_21_1907581078.1424967700691
Content-Type: multipart/alternative;
 boundary="----=_Part_22_931811883.1424967700691"

------=_Part_22_931811883.1424967700691
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Thursday, February 26, 2015 at 7:34:23 PM UTC+9, David Krauss wrote:
>
>
> On 2015=E2=80=9302=E2=80=9326, at 5:44 PM, antho...@gmail.com <javascript=
:> wrote:
>
>
>
> On Thursday, February 26, 2015 at 5:19:29 PM UTC+9, David Krauss wrote:
>>
>>
>> On 2015=E2=80=9302=E2=80=9326, at 3:26 PM, antho...@gmail.com wrote:
>>
>> The point is that fail() is set after stream >> n hits eof, without ther=
e=20
>> being "bad"/un-parsable input.
>>
>>
>> There was bad input, the dash character. And your proposal is that eofbi=
t=20
>> sometimes not be set at the EOF, not that failbit not be set after a=20
>> conversion failure.
>>
>
> What I mean by [[ "The point is that fail() is set after stream >> n hits=
=20
> eof, without there being "bad"/un-parsable input." ]] is that even when=
=20
> there's a simple eof condition (no longer talking about a hyphen), findin=
g=20
> it while attempting stream >> n sets both failbit and eofbit... after >>=
=20
> it's too late to differentiate.
>
>
> It sets failbit because n remains uninitialized. It sets eofbit because=
=20
> the stream is at eof.
>
> You=E2=80=99re essentially trying to specialize stream >> n for loop cond=
itions.=20
> Although the proposal =E2=80=9Cfixes=E2=80=9D the given case, the semanti=
cs become=20
> inconsistent and confusing for other cases. Usually eof is set whenever t=
he=20
> end of the stream is touched.
>

"touched" is vague.  If you simply open an ifstream on an empty file,=20
27.9.1.9 *guarantees* not to set eof(), and it's only after an I/O=20
operation on the file is attempted that the fail / eof flags come into=20
play.  Still, overall I agree the breaks with current behaviour aren't=20
acceptable.
=20

> If exceptions(std::ios::eofbit) is set, then the extractor might even=20
> lose control before observing the eof condition. Do you propose that be=
=20
> worked around?
>

I haven't given any thought to the exception case beyond consideration of=
=20
your earlier code.  It does sound problematic.
=20

> The solution is to use a more sophisticated loop.
>
> I'm not suggesting eof() be used... my proposal is to remove the need to=
=20
> use it to handle this situation.=20
>
>
> Your proposal is that eof shouldn=E2=80=99t be set when failbit is set, w=
hen the=20
> extractor already extracted a non-whitespace character. Given that, eof=
=20
> still needs to be called to differentiate failure due to no input at all=
=20
> (the =E2=80=9C3 4=E2=80=9D case, where you still expect eof to be set), f=
rom failure due to=20
> unexpected input at the end (the =E2=80=9C3 4 -=E2=80=9D case, where the =
state of eof is=20
> surprising to you).
>

It doesn't surprise me in the least... I'm saying it's inconveniently=20
ambiguous.=20

> Streams with bad input are differentiated by failbit. Period.
>>
>
> Again, the problem is failbit also happens when you try a final stream >>=
=20
> n when there's nothing (but possibly whitespace) left in the stream.=20
>
>
> There=E2=80=99s no way that failbit won=E2=80=99t be set by that operatio=
n: n remains=20
> uninitialized, so it=E2=80=99s a failure due to bad input.
>

No dispuiting that... the proposal was about effectively serialising the=20
reporting of failbit and eofbit.
=20

> The grammar expressed by while ( stream >> n ) is impossible to satisfy=
=20
> in finite time. If there=E2=80=99s no other exit condition, it *must* end=
 in=20
> failure.
>
> You can try making your proposal. I=E2=80=99m only one person here, and n=
ot a=20
> committee member. But my sensibility would be to fix the grammar and the=
=20
> loop, not the library. =E2=80=9CMost users=E2=80=9D just want to avoid en=
dless loops and=20
> UB, so your use case doesn=E2=80=99t sound as representative as it=E2=80=
=99s presented to=20
> be.
>

It's hardly uncommon to want to tell the user when their input can't be=20
parsed.  The proposal for types like int was largely to simplify the=20
implementation needed to detect corrupt or incomplete objects when writing=
=20
operator>> overloads for ones own types (explained in my original post).
=20

All that said, I'm starting to think if anything were to be done about=20
this, it might be better to propose a new flag (e.g. "partial",=20
"incomplete") rather than change the reporting of the current flags.  It's=
=20
pretty obvious how that would help the simple looping case, and for custom=
=20
overloads it might require something like...

    return is >> x.a_ >> x.set_partial >> x.b_ >> x.clear_partial;

....to return a proper value for the new flag.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_22_931811883.1424967700691
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 7:34:23 PM UTC+9=
, David Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div styl=
e=3D"word-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=
=E2=80=9302=E2=80=9326, at 5:44 PM, <a href=3D"javascript:" target=3D"_blan=
k" gdf-obfuscated-mailto=3D"3oQNB1ZCWx8J" rel=3D"nofollow" onmousedown=3D"t=
his.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:'=
;return true;">antho...@gmail.com</a> wrote:</div><br><div><div dir=3D"ltr"=
 style=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-varia=
nt:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-=
align:start;text-indent:0px;text-transform:none;white-space:normal;word-spa=
cing:0px"><br><br>On Thursday, February 26, 2015 at 5:19:29 PM UTC+9, David=
 Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><br><div=
><blockquote type=3D"cite"><div>On 2015=E2=80=9302=E2=80=9326, at 3:26 PM,<=
span>&nbsp;</span><a rel=3D"nofollow">antho...@</a><a href=3D"http://gmail.=
com/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http:/=
/gmail.com/';return true;" onclick=3D"this.href=3D'http://gmail.com/';retur=
n true;">gmail.com</a><span>&nbsp;</span>wrote:</div><br><div><div dir=3D"l=
tr" style=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-va=
riant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;te=
xt-align:start;text-indent:0px;text-transform:none;white-space:normal;word-=
spacing:0px">The point is that fail() is set after stream &gt;&gt; n hits e=
of, without there being "bad"/un-parsable input.</div></div></blockquote><d=
iv><br></div><div>There was bad input, the dash character. And your proposa=
l is that eofbit sometimes not be set at the EOF, not that failbit not be s=
et after a conversion failure.</div></div></div></blockquote><div><br>What =
I mean by [[ "The point is that fail() is set after stream &gt;&gt; n hits =
eof, without there being "bad"/un-parsable input." ]] is that even when the=
re's a simple eof condition (no longer talking about a hyphen), finding it =
while attempting stream &gt;&gt; n sets both failbit and eofbit... after &g=
t;&gt; it's too late to differentiate.<br></div></div></div></blockquote><d=
iv><br></div><div>It sets failbit because n remains uninitialized. It sets =
eofbit because the stream is at eof.</div><div><br></div><div>You=E2=80=99r=
e essentially trying to specialize&nbsp;<font face=3D"Courier">stream &gt;&=
gt; n</font> for loop conditions. Although the proposal =E2=80=9Cfixes=E2=
=80=9D the given case, the semantics become inconsistent and confusing for =
other cases. Usually eof is set whenever the end of the stream is touched.<=
/div></div></div></blockquote><div><br></div><div>"touched" is vague. &nbsp=
;If you simply open an ifstream on an empty file, 27.9.1.9&nbsp;<i>guarante=
es</i> not to set eof(), and it's only after an I/O operation on the file i=
s attempted that the fail / eof flags come into play. &nbsp;Still, overall =
I agree the breaks with current behaviour aren't acceptable.</div><div>&nbs=
p;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word=
-wrap:break-word"><div><div> If <font face=3D"Courier">exceptions(std::ios:=
:eofbit)</font> is set, then the extractor might even lose control before o=
bserving the eof condition. Do you propose that be worked around?</div></di=
v></div></blockquote><div><br></div><div>I haven't given any thought to the=
 exception case beyond consideration of your earlier code. &nbsp;It does so=
und problematic.</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div style=3D"word-wrap:break-word"><div><div>The solution is to u=
se a more sophisticated loop.</div><br><blockquote type=3D"cite"><div dir=
=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-style:normal;fo=
nt-variant:normal;font-weight:normal;letter-spacing:normal;line-height:norm=
al;text-align:start;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><div>I'm not suggesting eof() be used... my proposal is t=
o remove the need to use it to handle this situation.<span>&nbsp;</span><br=
></div></div></blockquote><div><br></div><div>Your proposal is that eof sho=
uldn=E2=80=99t be set when failbit is set, when the extractor already extra=
cted a non-whitespace character. Given that, eof still needs to be called t=
o differentiate failure due to no input at all (the =E2=80=9C3 4=E2=80=9D c=
ase, where you still expect eof to be set), from failure due to unexpected =
input at the end (the =E2=80=9C3 4 -=E2=80=9D case, where the state of eof =
is surprising to you).</div></div></div></blockquote><div><br></div><div>It=
 doesn't surprise me in the least... I'm saying it's inconveniently ambiguo=
us.&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"w=
ord-wrap:break-word"><div><blockquote type=3D"cite"><div dir=3D"ltr" style=
=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:nor=
mal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:=
start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0=
px"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:sol=
id;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><div>Streams =
with bad input are differentiated by<span>&nbsp;</span><font face=3D"Courie=
r">failbit</font>. Period.</div></div></div></blockquote><div><br>Again, th=
e problem is failbit also happens when you try a final stream &gt;&gt; n wh=
en there's nothing (but possibly whitespace) left in the stream.<span>&nbsp=
;</span><br></div></div></blockquote><div><br></div><div>There=E2=80=99s no=
 way that failbit won=E2=80=99t be set by that operation: n remains uniniti=
alized, so it=E2=80=99s a failure due to bad input.</div></div></div></bloc=
kquote><div><br></div><div>No dispuiting that... the proposal was about eff=
ectively serialising the reporting of failbit and eofbit.</div><div>&nbsp;<=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:b=
reak-word"><div><div>The grammar expressed by <font face=3D"Courier">while =
( stream &gt;&gt; n )</font> is impossible to satisfy in finite time. If th=
ere=E2=80=99s no other exit condition, it&nbsp;<i>must</i> end in failure.<=
/div><div><br></div><div>You can try making your proposal. I=E2=80=99m only=
 one person here, and not a committee member. But my sensibility would be t=
o fix the grammar and the loop, not the library. =E2=80=9CMost users=E2=80=
=9D just want to avoid endless loops and UB, so your use case doesn=E2=80=
=99t sound as representative as it=E2=80=99s presented to be.</div></div></=
div></blockquote><div><br></div><div>It's hardly uncommon to want to tell t=
he user when their input can't be parsed. &nbsp;The proposal for types like=
 int was largely to simplify the implementation needed to detect corrupt or=
 incomplete objects when writing operator&gt;&gt; overloads for ones own ty=
pes (explained in my original post).</div><div>&nbsp;</div><div><br></div><=
div>All that said, I'm starting to think if anything were to be done about =
this, it might be better to propose a new flag (e.g. "partial", "incomplete=
") rather than change the reporting of the current flags. &nbsp;It's pretty=
 obvious how that would help the simple looping case, and for custom overlo=
ads it might require something like...</div><div><br></div><div>&nbsp; &nbs=
p; return is &gt;&gt; x.a_ &gt;&gt; x.set_partial &gt;&gt; x.b_ &gt;&gt; x.=
clear_partial;</div><div><br></div><div>...to return a proper value for the=
 new flag.</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_22_931811883.1424967700691--
------=_Part_21_1907581078.1424967700691--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 26 Feb 2015 09:03:28 -0800 (PST)
Raw View
------=_Part_5895_977148631.1424970209002
Content-Type: multipart/alternative;
 boundary="----=_Part_5896_1129592608.1424970209002"

------=_Part_5896_1129592608.1424970209002
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le jeudi 26 f=C3=A9vrier 2015 10:31:48 UTC+1, antho...@gmail.com a =C3=A9cr=
it :
>
>
>> You tried to input something, that input failed.  There is indeed no=20
>> difference between failing due to missing data and bad data with >> if y=
ou=20
>> automatically skip over the whitespace. If you want to do so, you'll hav=
e=20
>> to skip the white space manually (and disable the possibility to skip=20
>> automatically, ws is using the sentry which set the error)
>>
>>     stream >> std::noskipws;
>>     while (stream >> std::ws && !stream.eof() && stream >> n) {
>>         std::cout << "got " << n << '\n';
>>     }
>>     if (stream.bad()) std::cout << "IO error\n";
>>     if (stream.fail()) std::cout << "Bad format\n";
>>
>
> It's the need for such code that precipitated my post.  I don't think C++=
=20
> newbies should be expected to write such code in order to do something as=
=20
> simple as parse numbers from a stream robustly.
> =20
>
>> Usually, the distinction doesn't worth the pain (maybe because I share=
=20
>> with the IOStream designers an Unix bias, Unix considers `\n` as line=20
>> terminator so non terminated last lines are oddities which can be ignore=
d=20
>> when IOStream formatted input is an adequate mechanism).
>>
>
> Same background here, but if istreams were necessarily files (and everyon=
e=20
> used sane editors) it would be less of a concern, but std::istringstreams=
=20
> initialised from string literals, network input etc. are quite likely not=
=20
> to be whitespace terminated.
>

Manually adding a space is easier than the above contortion for=20
stringstreams.

Exactly.  My point is: isn't that undesirable?  Shouldn't the library make=
=20
>>> it easy to see why the loop terminated?
>>>
>>
>> If you go to the point where error recovery is needed, IOStream formatte=
d=20
>> input is probably no more an adequate solution.
>>
>
> Currently yes, but could a proposal like this help rectify the situation?
>

IMHO, it address a minor corner case which doesn't make me drop IOStream.=
=20
 Robust parsing or even just lexing is something far harder.

Yours,

--=20
Jean-Marc

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_5896_1129592608.1424970209002
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le jeudi 26 f=C3=A9vrier 2015 10:31:48 UTC+1, antho...@gma=
il.com a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
 dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
<br></div><div>You tried to input something, that input failed. &nbsp;There=
 is indeed no difference between failing due to missing data and bad data w=
ith &gt;&gt; if you automatically skip over the whitespace. If you want to =
do so, you'll have to skip the white space manually (and disable the possib=
ility to skip automatically, ws is using the sentry which set the error)</d=
iv><div><br></div><div>&nbsp; &nbsp; stream &gt;&gt; std::noskipws;</div><d=
iv>&nbsp; &nbsp; while (stream &gt;&gt; std::ws &amp;&amp; !stream.eof() &a=
mp;&amp; stream &gt;&gt; n) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; std::co=
ut &lt;&lt; "got " &lt;&lt; n &lt;&lt; '\n';</div><div>&nbsp; &nbsp; }</div=
><div>&nbsp; &nbsp; if (stream.bad()) std::cout &lt;&lt; "IO error\n";</div=
><div>&nbsp; &nbsp; if (stream.fail()) std::cout &lt;&lt; "Bad format\n";</=
div></div></blockquote><div><br>It's the need for such code that precipitat=
ed my post.&nbsp; I don't think C++ newbies should be expected to write suc=
h code in order to do something as simple as parse numbers from a stream ro=
bustly.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr"><div>Usually, the distinction doesn't worth the pain (maybe because I =
share with the IOStream designers an Unix bias, Unix considers `\n` as line=
 terminator so non terminated last lines are oddities which can be ignored =
when IOStream formatted input is an adequate mechanism).</div></div></block=
quote><div><br>Same background here, but if istreams were necessarily files=
 (and everyone used sane editors) it would be less of a concern, but std::i=
stringstreams initialised from string literals, network input etc. are quit=
e likely not to be whitespace terminated.<br></div></div></blockquote><div>=
<br></div><div>Manually adding a space is easier than the above contortion =
for stringstreams.</div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Exac=
tly.&nbsp; My point is: isn't that undesirable?&nbsp; Shouldn't the library=
 make it easy to see why the loop terminated?<br></div></div></blockquote><=
div><br></div><div>If you go to the point where error recovery is needed, I=
OStream formatted input is probably no more an adequate solution.</div></di=
v></blockquote><div><br>Currently yes, but could a proposal like this help =
rectify the situation?<br></div></div></blockquote><div><br></div><div>IMHO=
, it address a minor corner case which doesn't make me drop IOStream. &nbsp=
;Robust parsing or even just lexing is something far harder.</div><div><br>=
</div><div>Yours,</div><div><br></div><div>--&nbsp;</div><div>Jean-Marc</di=
v></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5896_1129592608.1424970209002--
------=_Part_5895_977148631.1424970209002--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 26 Feb 2015 09:42:12 -0800 (PST)
Raw View
------=_Part_7114_1471717387.1424972532746
Content-Type: multipart/alternative;
 boundary="----=_Part_7115_437477163.1424972532746"

------=_Part_7115_437477163.1424972532746
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le jeudi 26 f=C3=A9vrier 2015 17:21:40 UTC+1, antho...@gmail.com a =C3=A9cr=
it :
>
>
>
> On Thursday, February 26, 2015 at 7:34:23 PM UTC+9, David Krauss wrote:
>>
>>
>> On 2015=E2=80=9302=E2=80=9326, at 5:44 PM, antho...@gmail.com wrote:
>>
>>
>>
>> On Thursday, February 26, 2015 at 5:19:29 PM UTC+9, David Krauss wrote:
>>>
>>>
>>> On 2015=E2=80=9302=E2=80=9326, at 3:26 PM, antho...@gmail.com wrote:
>>>
>>> The point is that fail() is set after stream >> n hits eof, without=20
>>> there being "bad"/un-parsable input.
>>>
>>>
>>> There was bad input, the dash character. And your proposal is that=20
>>> eofbit sometimes not be set at the EOF, not that failbit not be set aft=
er a=20
>>> conversion failure.
>>>
>>
>> What I mean by [[ "The point is that fail() is set after stream >> n hit=
s=20
>> eof, without there being "bad"/un-parsable input." ]] is that even when=
=20
>> there's a simple eof condition (no longer talking about a hyphen), findi=
ng=20
>> it while attempting stream >> n sets both failbit and eofbit... after >>=
=20
>> it's too late to differentiate.
>>
>>
>> It sets failbit because n remains uninitialized. It sets eofbit because=
=20
>> the stream is at eof.
>>
>> You=E2=80=99re essentially trying to specialize stream >> n for loop con=
ditions.=20
>> Although the proposal =E2=80=9Cfixes=E2=80=9D the given case, the semant=
ics become=20
>> inconsistent and confusing for other cases. Usually eof is set whenever =
the=20
>> end of the stream is touched.
>>
>
> "touched" is vague.  If you simply open an ifstream on an empty file,=20
> 27.9.1.9 *guarantees* not to set eof(), and it's only after an I/O=20
> operation on the file is attempted that the fail / eof flags come into=20
> play.  Still, overall I agree the breaks with current behaviour aren't=20
> acceptable.
>


There=E2=80=99s no way that failbit won=E2=80=99t be set by that operation:=
 n remains=20
>> uninitialized, so it=E2=80=99s a failure due to bad input.
>>
>
> No dispuiting that... the proposal was about effectively serialising the=
=20
> reporting of failbit and eofbit.
>

eofbit means "The streambuf has returned EOF and should no more be queried,=
=20
excepted if the user clear the condition".  I don't really like that=20
unget() clears eof , I've wondered in the past if the state wouldn't have=
=20
been better if the sentry had check eof && egptr=3D=3Dgptr instead of just =
eof,=20
and unget avoided clearing eof; that would also probably need some other=20
similar adjustments elsewhere.

All that said, I'm starting to think if anything were to be done about=20
> this, it might be better to propose a new flag (e.g. "partial",=20
> "incomplete") rather than change the reporting of the current flags.  It'=
s=20
> pretty obvious how that would help the simple looping case, and for custo=
m=20
> overloads it might require something like...
>
>     return is >> x.a_ >> x.set_partial >> x.b_ >> x.clear_partial;
>
> ...to return a proper value for the new flag.
>

I don't see how you can make it work for implementing >> using other >>=20
without using a scoped object holding the desired state for the desired=20
level.  But then, implementing << using << is also broken if you don't pay=
=20
attention to width handling.

--=20
Jean-Marc Bourguet

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_7115_437477163.1424972532746
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le jeudi 26 f=C3=A9vrier 2015 17:21:40 UTC+1, antho...@gma=
il.com a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
 dir=3D"ltr"><br><br>On Thursday, February 26, 2015 at 7:34:23 PM UTC+9, Da=
vid Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word=
-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=E2=80=930=
2=E2=80=9326, at 5:44 PM, <a rel=3D"nofollow">antho...@gmail.com</a> wrote:=
</div><br><div><div dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12=
px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:=
normal;line-height:normal;text-align:start;text-indent:0px;text-transform:n=
one;white-space:normal;word-spacing:0px"><br><br>On Thursday, February 26, =
2015 at 5:19:29 PM UTC+9, David Krauss wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-col=
or:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style=3D=
"word-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=E2=
=80=9302=E2=80=9326, at 3:26 PM,<span>&nbsp;</span><a rel=3D"nofollow">anth=
o...@</a><a href=3D"http://gmail.com/" rel=3D"nofollow" target=3D"_blank" o=
nmousedown=3D"this.href=3D'http://gmail.com/';return true;" onclick=3D"this=
..href=3D'http://gmail.com/';return true;">gmail.com</a><span>&nbsp;</span>w=
rote:</div><br><div><div dir=3D"ltr" style=3D"font-family:Helvetica;font-si=
ze:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spa=
cing:normal;line-height:normal;text-align:start;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px">The point is that fail() is s=
et after stream &gt;&gt; n hits eof, without there being "bad"/un-parsable =
input.</div></div></blockquote><div><br></div><div>There was bad input, the=
 dash character. And your proposal is that eofbit sometimes not be set at t=
he EOF, not that failbit not be set after a conversion failure.</div></div>=
</div></blockquote><div><br>What I mean by [[ "The point is that fail() is =
set after stream &gt;&gt; n hits eof, without there being "bad"/un-parsable=
 input." ]] is that even when there's a simple eof condition (no longer tal=
king about a hyphen), finding it while attempting stream &gt;&gt; n sets bo=
th failbit and eofbit... after &gt;&gt; it's too late to differentiate.<br>=
</div></div></div></blockquote><div><br></div><div>It sets failbit because =
n remains uninitialized. It sets eofbit because the stream is at eof.</div>=
<div><br></div><div>You=E2=80=99re essentially trying to specialize&nbsp;<f=
ont face=3D"Courier">stream &gt;&gt; n</font> for loop conditions. Although=
 the proposal =E2=80=9Cfixes=E2=80=9D the given case, the semantics become =
inconsistent and confusing for other cases. Usually eof is set whenever the=
 end of the stream is touched.</div></div></div></blockquote><div><br></div=
><div>"touched" is vague. &nbsp;If you simply open an ifstream on an empty =
file, 27.9.1.9&nbsp;<i>guarantees</i> not to set eof(), and it's only after=
 an I/O operation on the file is attempted that the fail / eof flags come i=
nto play. &nbsp;Still, overall I agree the breaks with current behaviour ar=
en't acceptable.</div></div></blockquote><div><br></div><div><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div><div>There=
=E2=80=99s no way that failbit won=E2=80=99t be set by that operation: n re=
mains uninitialized, so it=E2=80=99s a failure due to bad input.</div></div=
></div></blockquote><div><br></div><div>No dispuiting that... the proposal =
was about effectively serialising the reporting of failbit and eofbit.</div=
></div></blockquote><div><br></div><div>eofbit means "The streambuf has ret=
urned EOF and should no more be queried, excepted if the user clear the con=
dition". &nbsp;I don't really like that unget() clears eof , I've wondered =
in the past if the state wouldn't have been better if the sentry had check =
eof &amp;&amp; egptr=3D=3Dgptr instead of just eof, and unget avoided clear=
ing eof; that would also probably need some other similar adjustments elsew=
here.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
 dir=3D"ltr"><div>All that said, I'm starting to think if anything were to =
be done about this, it might be better to propose a new flag (e.g. "partial=
", "incomplete") rather than change the reporting of the current flags. &nb=
sp;It's pretty obvious how that would help the simple looping case, and for=
 custom overloads it might require something like...<br></div><div><br></di=
v><div>&nbsp; &nbsp; return is &gt;&gt; x.a_ &gt;&gt; x.set_partial &gt;&gt=
; x.b_ &gt;&gt; x.clear_partial;</div><div><br></div><div>...to return a pr=
oper value for the new flag.</div></div></blockquote><div><br></div><div>I =
don't see how you can make it work for implementing &gt;&gt; using other &g=
t;&gt; without using a scoped object holding the desired state for the desi=
red level. &nbsp;But then, implementing &lt;&lt; using &lt;&lt; is also bro=
ken if you don't pay attention to width handling.</div><div><br></div><div>=
--&nbsp;</div><div>Jean-Marc Bourguet</div><div><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_7115_437477163.1424972532746--
------=_Part_7114_1471717387.1424972532746--

.