C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

question on example code from Stroustrup::Design of C++0x

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
dmh2000
Guest





PostPosted: Tue Jul 12, 2005 12:46 am    Post subject: question on example code from Stroustrup::Design of C++0x Reply with quote



CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing? A google search shows other folks using
cin.get in this manner.

thanks
david howard
[email]daveh (AT) dmh2000 (DOT) com[/email]


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Abrahams
Guest





PostPosted: Tue Jul 12, 2005 8:28 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote



"dmh2000" <daveh (AT) dmh2000 (DOT) com> writes:

Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

Probably he means to indicate that this code is

a. overly complex

b. highly error-prone (how do you know if the array p points into
will be big enough?

Quote:
His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing?

Streams themselves are testable as boolean expressions via a
conversion operator. They convert to false when an error has
occurred.

HTH,
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
ThosRTanner
Guest





PostPosted: Tue Jul 12, 2005 8:33 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote





dmh2000 wrote:
Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

There is no size specified for p. Therefore it is not possible check
for overrunning of p.

For instance:
char password[20];
cout << "Please enter your password (8 to 10 chars): ";
get_input(&password[0]);

When this is run, a user types 'supercalifragelisticexpialidocious'.
Bang goes your program.

Quote:
His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing? A google search shows other folks using
cin.get in this manner.
There is a basic_istream::operator bool() which returns true unless

there has been an error.
<rant>
IMHO this is a rather vile kludge, which appears to be vaguely related
to the implicit cast of pointer or any integer to bool, inherited from
C.
</rant>

There is a good() method which returns true, and you could write:
"while (cin.get(ch).good()) {}" (or "while (cin.get(ch), cin.good()) {
}" if you find the first form makes you choke), with no loss of
clarity.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Heinz Ozwirk
Guest





PostPosted: Tue Jul 12, 2005 8:33 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

"dmh2000" <daveh (AT) dmh2000 (DOT) com> schrieb im Newsbeitrag
news:1121107287.497859.174050 (AT) o13g2000cwo (DOT) googlegroups.com...
Quote:
'while (cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing?

operator void*()

Each stream is convertable to void* and the conversion returns 0, if a
previous operation has failed.

HTH
Heinz



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ali Çehreli
Guest





PostPosted: Tue Jul 12, 2005 8:34 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

"dmh2000" <daveh (AT) dmh2000 (DOT) com> wrote

Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing? A google search shows other folks using
cin.get in this manner.

Your question applies to the alternative solution too, because 'cin >> s'
returns basic_istream& as well.

Streams can be used in place of a boolean expressions because they define
'operator void*'. That operator traditionally returns 0 when the stream is
unusable, and (I think) the address of the object when the stream is usable.
These two values decay to false and true respectably, in boolean contexts.

Ali

P.S. The reason streams don't define simply 'operator bool' is to prevent
accidentally using them in arithmetic expressions. It would be possible to
write 'cin + 42' had there been an 'operator bool' defined.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Gianluca Silvestri
Guest





PostPosted: Tue Jul 12, 2005 8:34 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote


"dmh2000" <daveh (AT) dmh2000 (DOT) com> ha scritto nel messaggio
news:1121107287.497859.174050 (AT) o13g2000cwo (DOT) googlegroups.com...
Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing? A google search shows other folks using
cin.get in this manner.

basic_ios<> has among his member functions the definition of operator

void*() const which can be used by the compiler in boolean contexts. In fact
its semantics is to return a null pointer whenever fail() returns true and a
pointer other than null to indicate success.

HTH
Gianluca


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Thomas Maeder
Guest





PostPosted: Tue Jul 12, 2005 8:35 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

"dmh2000" <daveh (AT) dmh2000 (DOT) com> writes:

Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0?

Stream classes are derived from a specialization of the basic_ios
template which has member functions

operator void*() const
bool operator!() const

The former will return a non-null pointer if and only if the stream's
fail() member function returns false

The latter returns the same value as fail().


The real thing I don't like about BS's code is that he didn't offer

if (cin >> s)

as an alternative rather than just

cin >> s

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Gene Bushuyev
Guest





PostPosted: Tue Jul 12, 2005 8:35 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

"dmh2000" <daveh (AT) dmh2000 (DOT) com> wrote

Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing? A google search shows other folks using
cin.get in this manner.

The answer is found in std::basic_ios class template that provides a
conversion operator:

operator void *( ) const;

which is 0 only when fail bit is set.
There is also another operator:

bool operator!( ) const;

which serves the same purpose.

Gene


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Thomas Tutone
Guest





PostPosted: Tue Jul 12, 2005 8:36 am    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

dmh2000 wrote:
Quote:
CUJ May 2005 has an article by Professor Stroustrup in which he gives a
couple of examples of bad code, but in one case he doesn't clearly
explain what is wrong.

void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it appears to
me the 'bad code' is actually wrong, not just sloppy. 'while
(cin.get(ch) ....)' shouldn't work. My library reference says
basic_istream::get(char) returns basic_istream&. How is that ever going
to be 0? What am I missing? A google search shows other folks using
cin.get in this manner.

std::cin has operator void*() const (or the moral equivalent) defined,
and that conversion function returns 0 when the stream is at end of
file or has an error condition. (It returns an implementation-defined
non-zero pointer otherwise.) This conversion is included so that
std::cin (and other streams) can be used in while and if statements
exactly as BS shows in the code you quoted.

But I think that the reason that BS considers this bad code is that
there is nothing to stop a buffer overrun - how ever much space you
provide in the buffer that p points to, the input from cin may be
larger. Using a std::string, as BS suggests as a better alternative,
avoids the possibility of such a buffer overrun.

Best regards,

Tom


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Jul 12, 2005 1:30 pm    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

dmh2000 wrote:
Quote:
CUJ May 2005 has an article by Professor Stroustrup in which
he gives a couple of examples of bad code, but in one case he
doesn't clearly explain what is wrong.

I've not read the article, but a priori, writing a function to
do something that is already provided for in the library is
wrong.

Quote:
void get_input(char* p)
{
char ch;
while (cin.get(ch) && !iswhite(ch)) *p++ = ch;
*p = 0;
}

His alternative solution is much simpler 'cin >> s'. But it
appears to me the 'bad code' is actually wrong, not just
sloppy.

It is wrong. It contains undefined behavior.

Quote:
'while (cin.get(ch) ....)' shouldn't work. My library
reference says basic_istream::get(char) returns
basic_istream&.

Then your library reference is wrong. It returns a pointer,
which will be null if the function fails.

Quote:
How is that ever going to be 0? What am I missing? A google
search shows other folks using cin.get in this manner.

The problem here isn't with the cin.get(ch). One of the
problems, already mentionned, is that the function doesn't check
the length. Presumably, in Stroustrups correct example, cin >>
s, s has type std::string -- otherwise, it suffers from the same
problem.

The other problem, of course, is that calling iswhite (which
should in fact be isspace) with a char as a parameter is
undefined behavior.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carl Barron
Guest





PostPosted: Tue Jul 12, 2005 4:22 pm    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

In article <1121166700.531122.290310 (AT) g43g2000cwa (DOT) googlegroups.com>,
<kanze (AT) gabi-soft (DOT) fr> wrote:

Quote:
'while (cin.get(ch) ....)' shouldn't work. My library
reference says basic_istream::get(char) returns
basic_istream&.

Then your library reference is wrong. It returns a pointer,
which will be null if the function fails.

Not according to my copy of the standard its prototype is
basic_istream<C,T> & basic_istream<C,T>::get(C &c);
[iso/iec 14882,section 27.6.1.3 para 5].

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Thomas Tutone
Guest





PostPosted: Tue Jul 12, 2005 10:42 pm    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:

[snip]

Quote:
'while (cin.get(ch) ....)' shouldn't work. My library
reference says basic_istream::get(char) returns
basic_istream&.

Then your library reference is wrong. It returns a pointer,
which will be null if the function fails.

My library references must be wrong too, then. Wink All of my
references say that basic_istream::get(char_type&) returns a
basic_istream&, as the OP said. That basic_istream& is then
convertible to a pointer to const void (which, as you said, will be
zero if the istream& isn't providing any more characters).

Best regards,

Tom


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Jul 13, 2005 12:54 pm    Post subject: Re: question on example code from Stroustrup::Design of C++0 Reply with quote

Thomas Tutone wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr wrote:

[snip]

'while (cin.get(ch) ....)' shouldn't work. My library
reference says basic_istream::get(char) returns
basic_istream&.

Then your library reference is wrong. It returns a pointer,
which will be null if the function fails.

My library references must be wrong too, then. Wink All of my
references say that basic_istream::get(char_type&) returns a
basic_istream&, as the OP said. That basic_istream& is then
convertible to a pointer to const void (which, as you said,
will be zero if the istream& isn't providing any more
characters).

Yes. I short-cut a few steps in there -- I'm so used to the way
I use streams, that I didn't think about the actual definition.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.