gets() rationale

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

gets() is universally acknowledged to be broken and useless; however,
it is still part of the standard library. Why? Is there enough
conforming code out there using gets() to justify retaining it? Are
there plans to deprecate or eliminate it in a future version?
 
E

Eric Sosman

Christopher said:
gets() is universally acknowledged to be broken and useless; however,
it is still part of the standard library. Why? Is there enough
conforming code out there using gets() to justify retaining it? Are
there plans to deprecate or eliminate it in a future version?

A question for comp.std.c, methinks. Follow-ups set.

At a guess, the Committee did not feel at liberty to
"reform" the traditional C library, even when hindsight
showed some of its features could have been better designed.
<varargs.h> was, I think, just about the only "subtraction,"
and the reason was that its traditional form was pretty
much unimplementable on certain machines of interest.
 
B

Ben Pfaff

Christopher Benson-Manica said:
gets() is universally acknowledged to be broken and useless; however,
it is still part of the standard library. Why? Is there enough
conforming code out there using gets() to justify retaining it? Are
there plans to deprecate or eliminate it in a future version?

Here is what the C99 rationale says:

30 7.19.7.7 The gets function

Because gets does not check for buffer overrun, it is
generally unsafe to use when its input is not under the
programmer's control. This has caused some to question
whether it should appear in the Standard at all. The
35 Committee decided that gets was useful and convenient in
those special circumstances when the programmer does have
adequate control over the input, and as longstanding
existing practice, it needed a standard specification. In
general, however, the preferred function is fgets (see
§7.19.7.2).
 
J

James Hu

gets() is universally acknowledged to be broken and useless; however,
it is still part of the standard library. Why? Is there enough
conforming code out there using gets() to justify retaining it? Are
there plans to deprecate or eliminate it in a future version?

A C compiler could generate a diagnostic when functions that are known
to be unsafe are used and suggest a safer alternative instead. (I seem
to remember seeing such warnings on the BSD version of gcc.)

-- James
 
D

Dan Pop

In said:
A C compiler could generate a diagnostic when functions that are known
to be unsafe are used and suggest a safer alternative instead. (I seem
to remember seeing such warnings on the BSD version of gcc.)

It's actually the linker that does it:

fangorn:~/tmp 26> gcc -c test.c
fangorn:~/tmp 27> gcc test.o
test.o: In function `main':
test.o(.text+0x7): the `gets' function is dangerous and should not be used.

Generating such warnings is a feature of GNU ld.

Dan
 
D

Dan Pop

In said:
gets() is universally acknowledged to be broken and useless; however,
it is still part of the standard library. Why? Is there enough
conforming code out there using gets() to justify retaining it? Are
there plans to deprecate or eliminate it in a future version?

The committee (lame) excuse is that their job was to standardise
existing practice and gets was existing practice. And, because it is
standardised, now, it continues to be existing practice, so there is no
hope to see it removed from the standard.

The real solution would have been to deprecate it in C89 and remove it in
C99. If some C99 program needed it badly, implementing gets() is a piece
of cake and a C99 program would have been allowed to define it. But they
missed the opportunity to fix this bug in the language and they are also
convinced that they did the right thing...

Dan
 
J

Joona I Palaste

The committee (lame) excuse is that their job was to standardise
existing practice and gets was existing practice. And, because it is
standardised, now, it continues to be existing practice, so there is no
hope to see it removed from the standard.

This begs the question, why was it existing practice in the first place?
What daemon possessed Dennis Ritchie to ever conceive it?
 
E

Eric

Joona I Palaste said:
This begs the question, why was it existing practice in the first place?
What daemon possessed Dennis Ritchie to ever conceive it?

Perhaps because of space limitations.

Once upon a time every single last byte was important and gets works
just fine and is all one needs in certain cases.
 
P

P.J. Plauger

Perhaps because of space limitations.

Once upon a time every single last byte was important and gets works
just fine and is all one needs in certain cases.

I don't know for sure, but I doubt that DMR is the perpetrator of
gets. For a period of time in the mid/late 1970s, all sorts of
people were throwing functions into the C library (and applications
into the set of Unix tools, and even system calls into the Unix
kernel). Not all of these were well thought out.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
L

Les Cargill

Joona said:
This begs the question, why was it existing practice in the first place?
What daemon possessed Dennis Ritchie to ever conceive it?

The 'C' libraries evoved, and were not necessarily designed from a
rigorous set of requirements ( beyond what they were designed from).

"Doctor, doctor, it hurts when I do that."
"Well, don't do that."
 
D

Dan Pop

In said:
This begs the question, why was it existing practice in the first place?
What daemon possessed Dennis Ritchie to ever conceive it?

What makes you think gets() is Ritchie's brainchild? There is no mention
of gets() in K&R1 at all...

Dan
 
J

Joona I Palaste

What makes you think gets() is Ritchie's brainchild? There is no mention
of gets() in K&R1 at all...

What made me think it was Ritchie's brainchild is that it's quite a
basic C function, and C is Ritchie's brainchild. But I haven't read
K&R1 in a while, so I forgot it wasn't there.
But the question remains: why did *anyone* invent gets() in the first
place?

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"And according to Occam's Toothbrush, we only need to optimise the most frequent
instructions."
- Teemu Kerola
 
D

Dan Pop

In said:
What made me think it was Ritchie's brainchild is that it's quite a
basic C function, and C is Ritchie's brainchild.

That's very poor reasoning. The C we're talking about here hardly
qualifies as Ritchie's brainchild.
But I haven't read K&R1 in a while, so I forgot it wasn't there.

When was the last time you read it? ;-)
But the question remains: why did *anyone* invent gets() in the first
place?

For the same reason zillions of other people think that it is a good idea
to use it: it's much easier to use than fgets. Apart from that, there is
really nothing wrong with using gets() in toy programs, that are not
meant to be used by anyone but you and which are deleted as soon as they
have been fully debugged.

If you're perfectly aware of the safety issues involved, you can decide
when to use gets() and when not. There is little point in putting more
safety into a program than actually needed, especially considering that
this extra safety is not obtained for free.

Dan
 
W

Will

and maybe strcpy() should go too since it does not (cannot) check how much
it can copy? Long live to memcpy()!
 
J

Joona I Palaste

Will said:
and maybe strcpy() should go too since it does not (cannot) check how much
it can copy? Long live to memcpy()!

Umm... have you heard of strlen()?
 
K

Keith Thompson

and maybe strcpy() should go too since it does not (cannot) check how much
it can copy? Long live to memcpy()!

The program has complete control over the arguments it passes to
strcpy(). Most programs have no direct control over what's sent to
them on stdin.
 
W

Will

If u suggest calling strlen() before calling strcpy() *EVERY TIME*, u
are suggesting yet another problem. It's so easy to blow strlen().
 
A

Arthur J. O'Dwyer

If u suggest calling strlen() before calling strcpy() *EVERY TIME*, u
are suggesting yet another problem. It's so easy to blow strlen().


Because it's annoying as hell.
Why not?
Please don't top-post.


Joona's point (or at least the point I would have made if I were
Joona) was that

char *p = "foo";
char q[4];
strcpy(q, p);

is *perfectly* correct, while anything along the lines of

char p[100000];
gets(p);

is *broken by design*. There's simply no possible comparison between
gets() and strcpy() as far as correctness goes.
Your response made it sound as if you thought strcpy() could possibly
copy an arbitrarily large number of characters without the programmer's
knowing about it. So (I assume) Joona mentioned the strlen() function,
which is a portable and safe way of finding out exactly *how many*
characters strcpy() is going to be copying at any time. If you can't
keep track of the length of some string yourself, strlen() is always
available.

Oh, and of course it's impossible to "blow" strlen(), unless you
suggest passing NULL or some other non-string pointer to it. Sure,
you can crash your program with

int p;
strlen((void*)&p);

any time you like. But that's just silly; I don't think you could
have been referring to that. Which leads me to the conclusion that
you were confused when you wrote
It's so easy to blow strlen().

HTH,
-Arthur
 
C

CBFalconer

Will wrote: *** top posting fixed ***
If u suggest calling strlen() before calling strcpy() *EVERY TIME*,
u are suggesting yet another problem. It's so easy to blow strlen().

STOP the rude top-posting, please. The point is not that it is
possible to misuse strcpy and strlen, but that it is impossible to
prevent misuse of gets. You can only 'blow' strlen if you apply
it to something that is not a string, in the C sense. You always
have control over the creation of that string.
 
A

Alan Balmer

If u suggest calling strlen() before calling strcpy() *EVERY TIME*, u
are suggesting yet another problem. It's so easy to blow strlen().
Please don't top-post. Please stop the annoying practice of writing
"u" when you mean "you."

What Joona was suggesting was that you use strlen whenever needed to
determine the length of a string. Not "never", not "always", but
whenever the situation calls for it. But you already knew that, didn't
you?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top