Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sloppy wording around formatted/unformatted input/output functions #4717

Open
jwakely opened this issue Jun 25, 2021 · 1 comment
Open

Sloppy wording around formatted/unformatted input/output functions #4717

jwakely opened this issue Jun 25, 2021 · 1 comment
Assignees

Comments

@jwakely
Copy link
Member

jwakely commented Jun 25, 2021

[istream.formatted.reqmts] says:

Each formatted input function begins execution by constructing an object of class sentry with the noskipws
(second) argument false.

What's the first argument?

If the sentry object returns true, when converted to a value of type bool,

We should refer to contextually conversion to bool, [conv.general].

the function endeavors to obtain the requested input.

I don't think "endeavors" is a great choice of word here, and what's "the requested input"? Especially in the context of [ostream.unformatted] where "requested output" isn't clear for basic_ostream::flush().

If an exception is thrown during input

What if it's thrown and caught so that it never reaches the formatted input function?

then ios_base::badbit is turned on(294) in *this’s error state.
(footnote 294) This is done without causing an ios_base::failure to be thrown.

That footnote seems normative.

If (exceptions()&badbit) != 0 then the exception is rethrown.

Sometimes we have space around the & operator and sometimes we don't.

In any case, the formatted input function destroys the sentry object.

Code font for "sentry"?

If no exception has been thrown, it returns *this.

Not all formatted input functions are members, e.g. [istream.extractors] p7 says "Behaves like a formatted input member (as described in 29.7.4.3.1) of in". Maybe it's reasonable to substitute &in for this, but what we define above is a "formatted input function" not a "formatted input member". [istream.manip] p12 just says "Behaves as an unformatted input function" for a non-member, without saying what should be used for *this (obviously it's is but we don't say so).

The whole thing is a bit sloppy and muddled. And then we use almost the same words in [istream.unformatted], [ostream.formatted.reqmts], and [ostream.unformatted], but with slight differences that makes it awkward to compare them. Are the variations in phrasing significant? You have to read them carefully to realise that no, most of the variation makes no difference.

We could say that a formatted/unformatted input/output function has an associated object, which is *this for member functions, and be sure to always say what that object is for non-members. And we should state that the sentry is constructed with that object as its first argument!

Maybe something like:

Each formatted input function has an associated object,
which is *this for member functions.
The function begins execution by constructing an object of class sentry
with the associated object as the first argument,
and false as the noskipws (second) argument.
The effects specified for the function are only performed if
the sentry object yields true
when contextually converted to bool ([conv.general]).
If evaluation of the effects ends by throwing an exception
then ios_base::badbit is turned on in *this's error state,
without causing an ios_base::failure to be thrown.
If (exceptions() & badbit) != 0 then the exception is rethrown.
In any case, the formatted input function destroys the sentry object.
Unless the function exits via an exception, it returns the associated object.

We could also remove the unnecessary variation in the four versions of this wording. We could introduce a new definition, something like "using a sentry", for the common parts of the four definitions, and then stop repeating it in slightly different ways. Then the definitions of formatted/unformatted input/output functions could refer to that for the common properties, and only need to describe the ways in which they differ.

@jwakely jwakely self-assigned this Jun 25, 2021
@jwakely
Copy link
Member Author

jwakely commented Jun 25, 2021

Also, basic_ostream::flush() is an unformatted output functions (since LWG 581), but it does not "begin execution by constructing a sentry object" because it first checks if rdbuf() is null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant