Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PPP2] page 360: The else branch will never be reached

21 views
Skip to first unread message

Christiano

unread,
Mar 12, 2017, 12:46:45 PM3/12/17
to
In the book [1], page 360

The code is:

#include <iostream>
#include <stdexcept>

int main()
{
std::cout << "Please, enter an integer in the range 1 to 10
(inclusive):\n";
int n = 0;

while(true) {
std::cin >> n;

if(std::cin) { // Region 1
if(1<=n && n<=10) break;
std::cout << "Sorry, " << n << " is not in the [1:10]
range; please, try again\n";

}
else if(std::cin.fail()) { // Region 2
std::cin.clear();

std::cout << "Sorry, that was not a number; please try
again\n";
for(char ch; std::cin>>ch && !isdigit(ch);)
std::cout << "repeat\n";
if(!std::cin)
throw std::runtime_error("no input");
std::cin.unget();


}
else { // Region 3
// book says here : "eof or bad: give up "
throw std::runtime_error("no input");
}
}

return 0;
}

The problem is that the region 3 will never be reached.
The negation of bool "std::cin" is the bool "std::cin.fail()", according
to ISO/IEC 14882:2011 27.5.5.4, therefore, the condition " else
if(std::cin.fail()) " is a redundancy since if the flux control goes
through the "else" of region 2 then it only has happened because
std::cin.fail() is true. The effect of this is that Region 3 will never
be reached, although the book Region3 comment: "// eof or bad: give up"(
= [c]).
Regarding the commentary [c]:
First, bad will be detected by fail(), according with ISO/IEC
14882:2011(E) 27.5.5.4.9.
Secondly, eof will cause a fail-set, because it generate a format
problem, therefore the eof will be detected also by first "if" (so
entering in the region 2).

Testing (Text inside "****" is my comment) :

debian@debian:~/principles/project2$ ./a.out
Please, enter an integer in the range 1 to 10 (inclusive):
******* HERE I PRESS CTRL+D (LINUX) TO FORCE A END OF FILE **************
Sorry, that was not a number; please try again ***** EOF ENTER
REGION 2 AS MY EXPECTATION ****
1
debian@debian:~/principles/project2$

My conclusion is that this code is confusing because the last branch
will never be accessed.
But I am just learning the C ++ language and therefore I would like to
hear the opinion of the most experienced.

For the learner any little mistake in the book is a mountain generating
doubts.

[1] http://stroustrup.com/Programming/
ISBN 978-0-321-99278-9
Fourth Printing
Programming: Principles and Practice using C++ (Second Edition)
In respect to the group and author: I have the original book;
using here only a little portion of the book for
educational/research purposes according to fair use.

Alf P. Steinbach

unread,
Mar 12, 2017, 1:05:16 PM3/12/17
to
That's a bug all right. Good catch!


[snip]
> But I am just learning the C ++ language and therefore I would like to
> hear the opinion of the most experienced.

Note: logic can nearly always be trusted.

This bug is not in the second edition's errata list at <url:
http://www.stroustrup.com/Programming/PPP2errata.html>.

But how to report it?

Apparently Bjarne has removed his e-mail address from the web, and I see
no contact information for the book. But people have managed to contact
him. After all, there /is/ an errata list, and thanks to people for
contributing. So maybe I'm blind. That I just don't see it.

Anyway, according to gmail, the last mail address I had for him was
(rot-13-encoded, at-sign spelled out) "of at pf.gnzh.rqh"; as it
happened we discussed just that book. ;-)


Cheers & hth.,

- Alf

Alf P. Steinbach

unread,
Mar 12, 2017, 1:30:27 PM3/12/17
to
On 12-Mar-17 6:05 PM, Alf P. Steinbach wrote:
>
[snip]
> Anyway, according to gmail, the last mail address I had for him was
> (rot-13-encoded, at-sign spelled out) "of at pf.gnzh.rqh"; as it
> happened we discussed just that book. ;-)

Oh. Found:
<url: https://parasol.tamu.edu/~bs/>


Cheers!,

- Alf

Christiano

unread,
Mar 12, 2017, 4:33:51 PM3/12/17
to
Hi, Alf,

I already contacted him saying that I would report *possible* bugs in
the specific group about the book:
https://groups.google.com/forum/#!forum/ppp-public
So he could search when he has an interest.
I'd rather not contact him directly because this can be considered an
excess.

Thank you

Alf P. Steinbach

unread,
Mar 12, 2017, 5:37:24 PM3/12/17
to
Oh, well this is a definite bug. `if( !x ) {...} else if( x ) { ... }
else { /* spurious conclusion */ }`. There's no “possible” about it,
it's very definitely a bug.

As far as I know Bjarne has always tried to reply to clc++ users who
contacted him. Around 10 years ago or so he still posted here. The last
clc++ posting of his I found now was in 2006, as a response to me, but
that's because I remembered what to search for, the intentional
¹misspeling. I don't think he reads this group anymore; too much noise,
at least when one doesn't use a newsreader with noise filters. It's
possible though that he reads the dedicated-to-PPP Google group.

But I think he will be happy if you contact him about a definite error
in the book. You can just write that an old Norwegian Usenet denizen
name of Alf told you to. It helps the community to have things fixed. ;-)


Cheers!,

- Alf

¹ <url:
https://groups.google.com/d/msg/comp.lang.c++/PbywU1s6sqI/TJjnFd4xYYsJ>

Barry Schwarz

unread,
Mar 12, 2017, 7:27:23 PM3/12/17
to
On Sun, 12 Mar 2017 22:37:14 +0100, "Alf P. Steinbach"
<alf.p.stein...@gmail.com> wrote:

>On 12-Mar-17 9:34 PM, Christiano wrote:
>> On 03/12/2017 02:30 PM, Alf P. Steinbach wrote:
>>> On 12-Mar-17 6:05 PM, Alf P. Steinbach wrote:
>>>>
>>> [snip]
>>>> Anyway, according to gmail, the last mail address I had for him was
>>>> (rot-13-encoded, at-sign spelled out) "of at pf.gnzh.rqh"; as it
>>>> happened we discussed just that book. ;-)
>>>
>>> Oh. Found:
>>> <url: https://parasol.tamu.edu/~bs/>
>>>
>>>
>>> Cheers!,
>>>
>>> - Alf
>>>
>>
>> Hi, Alf,
>>
>> I already contacted him saying that I would report *possible* bugs in
>> the specific group about the book:
>> https://groups.google.com/forum/#!forum/ppp-public
>> So he could search when he has an interest.
>> I'd rather not contact him directly because this can be considered an
>> excess.
>
>Oh, well this is a definite bug. `if( !x ) {...} else if( x ) { ... }
>else { /* spurious conclusion */ }`. There's no “possible” about it,
>it's very definitely a bug.

If the two if expressions are identical except for the '!', one could
make a valid argument for this. But in the case in question was not
std::cin and !std.cin. It was std.cin and std::cin.fail(). Is the
compiler expected to know the ramifications of every class and member
function in the standard library?

It would be interesting to see which compilers do a better job if
std:cin.fail() is replace with !std::cin. Mine does not.

--
Remove del for email

Alf P. Steinbach

unread,
Mar 12, 2017, 8:12:12 PM3/12/17
to
C++14 $27.5.5.4/1:

[quote]
explicit operator bool() const;
Returns: !fail()
[/quote]

This conversion of stream object to boolean, used in `if( cin )` in the
book's code, has been defined directly in terms of `fail()` since C++98.
The only difference is that since C++11 it's been defined as `explicit
operator bool`, while in C++98 it was an `operator void`, because C++98
didn't support `explicit` for a conversion operator.


> Is the
> compiler expected to know the ramifications of every class and member
> function in the standard library?

No, but /we/ are expected to know what the things we use, do. ;-)

And the logic is unaffected by what the compiler is able to deduce.

/We/ know that `fail` doesn't modify the object, and hence that the two
conditions must have opposite results, even though the compiler doesn't.


> It would be interesting to see which compilers do a better job if
> std:cin.fail() is replace with !std::cin. Mine does not.

If you mean that it ideally should warn about that code, well, the
problem there is that the average compiler doesn't know that `fail`
can't change the state of the stream object. For the `const`-ness of
that member function doesn't prevent `fail` from modifying, even if
that's clearly /indicated/ and even if it's not circumvented by
`mutable` or `const_cast`. That's because the stream object might have
e.g. a pointer to an owned, mutable buffer that `fail` conceivably could
modify, and on which its result could depend.

This problem, that the compiler can't see the intended pure inspection
function nature of `fail` without having that knowledge hardwired, is
because the standard language (unfortunately) has no way to express in
general that a function is pure. `constexpr` comes close. But it does
not correspond exactly, and it's not applicable here.

Still, when I tested this now I was surprised that g++ didn't warn,
because I seem to recall that g++ has a language extension that allows
one to annotate a function as pure, and I'd expect that to be used in
its standard library implementation, for improved diagnostics. But alas.


Cheers!,

- Alf

Alf P. Steinbach

unread,
Mar 12, 2017, 8:16:01 PM3/12/17
to
On 13-Mar-17 1:11 AM, Alf P. Steinbach wrote:
> it was an `operator void`,

void*

Mumble, grumble.


Cheers!,

- Alf

0 new messages