472,146 Members | 1,283 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,146 software developers and data experts.

Why is it dangerous?

'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows? Where can I download a
non dangerous gets function? I have never used gets before is
there undefined behavior somewhere?
Here is a trimmed down example program from my assignment that
demonstrates the problem

#include <stdio.h>
#include <malloc.h>

void main()
{
char *string;
printf("enter string (max 2000 chars): ");
fflush(stdin);
fflush(stdout);
string = (char *)malloc(2001);
if(!string) exit(1);
gets(string);
printf("you entered: %s\n", string);
free(string);
exit(0);
}

On windows with TurboC and Lcc no error is printed. On linux with
gcc it says gets is dangerous.

Please advise my instructor says gcc is overly pedantic.
Aug 10 '08
233 8092
On 11 Aug 2008 at 22:17, Richard Heathfield wrote:
Willem said:
>The person driviong that other car would, if you were killed, have the
very traumatic experience of having caused your death, as opposed to just
causing you some injuries had you worn your seatbelt.

They might also suffer the even more traumatic experience of having you
smash through their windscreen, injuring or even killing them.
Oh come on, has this ever actually happened? It's no surprise that you
take the authoritarian view on this, but don't invent facts to support
your "case".
>So by choosing not to wear your seatbelt you put others in danger of
being traumatized by your death.

And possibly their own.
Pure hyperbolic melodrama!

Aug 11 '08 #51
James Dow Allen wrote:
>
.... snip about gets ...
>
Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)
They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.

I assume you use it because of the simplicity of the call. You can
get that simplicity, together with safety, by using ggets. All you
have to do is free the returned string when you are done with it.
It is available, written in standard C, and put in the public
domain, at:

<http://cbfalconer.home.att.net/download/ggets.zip>

EX:
char *line;
...
while (0 == ggets(&line)) {
/* use the line */
free(line);
}

or you can keep the returned line as long as you need it.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 11 '08 #52
CBFalconer <cb********@yahoo.comwrites:
James Dow Allen wrote:
>>
... snip about gets ...
>>
Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)

They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.

I assume you use it because of the simplicity of the call. You can
get that simplicity, together with safety, by using ggets.
How does ggets overcome the problem you've just identified with the
OP's use of gets?

--
Ben.
Aug 12 '08 #53
On Aug 11, 12:25 pm, gor...@hammy.burditt.org (Gordon Burditt) wrote:
The way to get rid of the warning on gets(), if you really want to
do it, is (on FreeBSD, anyway, but I suspect it applies to other
systems that use gcc as a default compiler):

(1) Remove the call to __warn_references() in gets.c .
(2) Rebuild the C library.

Rebuilding the compiler isn't necessary.
You can also

objcopy -R .gnu.warning.gets /usr/lib/libc.a

Repeat for libc.so, etc.

It's a little surprising that 'ld' doesn't appear to have an option to
suppress these.
Aug 12 '08 #54
On 2008-08-12, Ben Bacarisse <be********@bsb.me.ukwrote:
CBFalconer <cb********@yahoo.comwrites:
>>
I assume you use it because of the simplicity of the call. You can
get that simplicity, together with safety, by using ggets.

How does ggets overcome the problem you've just identified with the
OP's use of gets?
ggets() interally allocates a dynamically-resized buffer. In the case
that it runs out of memory, it returns an appropriate error condition.

On the other hand, if you really do have "complete control" over your
input, it would be cheaper to use fgets(), since you can use a fixed-
size buffer and the sizeof operator.

The choice is one between convienence and raw efficiency. Neither one
equates to using gets().

--
Andrew Poelstra ap*******@wpsoftware.com
To email me, use the above email addresss with .com set to .net
Aug 12 '08 #55
Ben Bacarisse wrote:
CBFalconer <cb********@yahoo.comwrites:
>James Dow Allen wrote:
>>>
... snip about gets ...
>>>
Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)

They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.

I assume you use it because of the simplicity of the call. You
can get that simplicity, together with safety, by using ggets.

How does ggets overcome the problem you've just identified with
the OP's use of gets?
I suggest you download it and see for yourself. It is only about
an 11k download.

<http://cbfalconer.home.att.net/download/ggets.zip>

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 12 '08 #56
Ben Bacarisse said:
CBFalconer <cb********@yahoo.comwrites:
>James Dow Allen wrote:
>>>
... snip about gets ...
>>>
Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)

They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.

I assume you use it because of the simplicity of the call. You can
get that simplicity, together with safety, by using ggets.

How does ggets overcome the problem you've just identified with the
OP's use of gets?
It doesn't - insofar as it makes no special provision against one-bit
errors in reading a '\n' from your prewritten data. It does, however,
return an error if it runs out of memory. But it fails to take the obvious
precaution of allowing the caller to specify an upper limit to the number
of bytes taken from the stream.

So let's say you have this situation - you know your lines are no longer
than 6 bytes (the same argument applies to more typical line lengths, eg
72 or 80, but the much lower value is chosen simply because it is easy to
write and easy to read in a Usenet article).

Here are your data:

3.141
1.618

A one bit error in reading a '\n' from the 3.141 line results in it being
interpreted as a J instead (01001010 instead of 00001010). So if ggets
really did overcome this obstacle, it would detect the one-bit error and
correct for it or at least report it. In practice, what ggets will do is
read the next line too, so that you'll get:

3.141J1.618

which is very much *not* what is intended. Now, I'm not saying that ggets
*should* be able to defend against bit errors like this. I'm saying it
*doesn't*.

I have suggested, many times, that Mr Falconer should add a "maximum bytes
to read" parameter to ggets - and doing so would offer the caller a
reasonable line of defence against such an error: rc = ggets(&line, 6)
would give you a fighting chance of at least detecting that something is
wrong in the above situation. But ggets in its current state does not, so
the *best* you can hope for is that you run out of memory. Not a happy
state of affairs.

Again, I stress that there is no shame in an input routine not detecting
bit errors of this kind. But ggets was offered, by its author, as a
solution to the problem of a one bit error in reading a '\n' - and it is
no such thing.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 12 '08 #57
Richard Heathfield wrote:
>
.... snip ...
>
Again, I stress that there is no shame in an input routine not
detecting bit errors of this kind. But ggets was offered, by its
author, as a solution to the problem of a one bit error in
reading a '\n' - and it is no such thing.
No I didn't. It is a solution to having such an error blow up your
machine. Your long mischaracterization is not helping anybody.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

Aug 12 '08 #58
CBFalconer said:
Richard Heathfield wrote:
>>
... snip ...
>>
Again, I stress that there is no shame in an input routine not
detecting bit errors of this kind. But ggets was offered, by its
author, as a solution to the problem of a one bit error in
reading a '\n' - and it is no such thing.

No I didn't.
Then I am at a loss to explain your previous response.
It is a solution to having such an error blow up your machine.
Perhaps you could explain how such an error could blow up one's machine in
the first place.
Your long mischaracterization is not helping anybody.
Well, obviously I don't agree that it's a mischaracterization. Neither do I
agree that it is necessarily of no help to anybody. Perhaps you could
explain precisely why you think it is a mischaracterization.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 12 '08 #59
On Aug 12, 9:43 am, Richard Heathfield <r...@see.sig.invalidwrote:
<snip>
It doesn't - insofar as it makes no special provision against one-bit
errors in reading a '\n' from your prewritten data. It does, however,
return an error if it runs out of memory. But it fails to take the obvious
precaution of allowing the caller to specify an upper limit to the number
of bytes taken from the stream.

So let's say you have this situation - you know your lines are no longer
than 6 bytes (the same argument applies to more typical line lengths, eg
72 or 80, but the much lower value is chosen simply because it is easy to
write and easy to read in a Usenet article).

Here are your data:

3.141
1.618

A one bit error in reading a '\n' from the 3.141 line results in it being
interpreted as a J instead (01001010 instead of 00001010). So if ggets
really did overcome this obstacle, it would detect the one-bit error and
correct for it or at least report it. In practice, what ggets will do is
read the next line too, so that you'll get:
<snip>

What is this one-bit error you are talking about? It's the first time
I hear it.
Assuming that error happends, wouldn't the error flag for the stream
be set?
Aug 12 '08 #60
Andrew Poelstra <no****@nospam.comwrites:
On 2008-08-12, Ben Bacarisse <be********@bsb.me.ukwrote:
>CBFalconer <cb********@yahoo.comwrites:
>>>
I assume you use it because of the simplicity of the call. You can
get that simplicity, together with safety, by using ggets.

How does ggets overcome the problem you've just identified with the
OP's use of gets?

ggets() interally allocates a dynamically-resized buffer. In the case
that it runs out of memory, it returns an appropriate error
condition.
You've snipped the "problem" so my objection has been lost. What I
was saying (and it is a bit of a wild card) is how can any routine be
safe in the presence of bit errors in the input? I don't think it is
reasonable to assume that stdio works under these conditions. We have
no reasonable method to reason about what a program does when the
input system does not deliver the input.

<snip>

--
Ben.
Aug 12 '08 #61
CBFalconer <cb********@yahoo.comwrites:
Ben Bacarisse wrote:
>CBFalconer <cb********@yahoo.comwrites:
>>James Dow Allen wrote:

... snip about gets ...

Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)

They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.

I assume you use it because of the simplicity of the call. You
can get that simplicity, together with safety, by using ggets.

How does ggets overcome the problem you've just identified with
the OP's use of gets?

I suggest you download it and see for yourself. It is only about
an 11k download.
I was not explicit enough. I my book, once stdio has "gone wrong"
i.e. not done what it should, I think you are into a special kind UB
and all bets are off. You recently posted (in another group) that
evaluating ++a + a++ might erase all files on all discs but you are
prepared to say that one program is safer than another when stdio is
not working correctly?

From an engineering point of you are 100% right, and if you normally
posted from the "what a computer will usually do" point of view, I
would probably have said nothing, but seem to be an all-or-nothing
poster about UB.
<http://cbfalconer.home.att.net/download/ggets.zip>
--
Ben.
Aug 12 '08 #62
vi******@gmail.com said:
On Aug 12, 9:43 am, Richard Heathfield <r...@see.sig.invalidwrote:
<snip>
>A one bit error in reading a '\n' from the 3.141 line results in it
being interpreted as a J instead (01001010 instead of 00001010). So if
ggets really did overcome this obstacle, it would detect the one-bit
error and correct for it or at least report it. In practice, what ggets
will do is read the next line too, so that you'll get:

<snip>

What is this one-bit error you are talking about?
You might want to ask CBFalconer that, since it was he who raised the
subject, in Message-ID: <48**************@yahoo.com>
It's the first time I hear it.
Assuming that error happends, wouldn't the error flag for the stream
be set?
No idea. I've never heard of it either.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 12 '08 #63
On Aug 12, 1:24 am, CBFalconer <cbfalco...@yahoo.comwrote:
James Dow Allen wrote:

Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)

They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.
What is this one bit error you are talking about?
Aug 12 '08 #64
In article <sl*******************@nospam.invalid>, Antoninus Twink <no****@nospam.invalidwrote:
>Usually these "complaints" are just the observation that
self-determination is a pretty fundamental liberty that we should have
in a free society. The state has *no damn business* telling me what I
should or shouldn't do in the privacy of my own car, when it doesn't
affect anyone's safety but my own.
Safety is not the only aspect to consider: since insurance is based on the
concept of average, or shared, risk across a large pool of insured, *everyone*
pays higher insurance costs because of the knuckleheads who refuse to wear
seat belts.
Aug 12 '08 #65
Richard Heathfield wrote:
CBFalconer said:
>Richard Heathfield wrote:
>>>
... snip ...
>>>
Again, I stress that there is no shame in an input routine not
detecting bit errors of this kind. But ggets was offered, by its
author, as a solution to the problem of a one bit error in
reading a '\n' - and it is no such thing.

No I didn't.

Then I am at a loss to explain your previous response.
Maybe you should take a course in reading.
>
>It is a solution to having such an error blow up your machine.

Perhaps you could explain how such an error could blow up one's
machine in the first place.
Do you want a probability graph? Based on random data, which is
not what will be inserted on such an error.
>
>Your long mischaracterization is not helping anybody.
--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 12 '08 #66
vi******@gmail.com wrote:
CBFalconer <cbfalco...@yahoo.comwrote:
>James Dow Allen wrote:
>>Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)

They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.

What is this one bit error you are talking about?
Who cares? With the error the '\n' is no longer a '\n', and thus
the line is not ended, and gets can happily overwrite
who-knows-what with whatever.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

Aug 12 '08 #67
CBFalconer said:
Richard Heathfield wrote:
>CBFalconer said:
>>Richard Heathfield wrote:

... snip ...

Again, I stress that there is no shame in an input routine not
detecting bit errors of this kind. But ggets was offered, by its
author, as a solution to the problem of a one bit error in
reading a '\n' - and it is no such thing.

No I didn't.

Then I am at a loss to explain your previous response.

Maybe you should take a course in reading.
Perhaps. Nevertheless, I am still at a loss to explain your previous
response. Maybe you could enlighten me.
>>It is a solution to having such an error blow up your machine.

Perhaps you could explain how such an error could blow up one's
machine in the first place.

Do you want a probability graph?
If you like, but a simple explanation will do.
Based on random data, which is
not what will be inserted on such an error.
Perhaps you could explain what /will/ be inserted on such an error, and how
it could blow up a machine.
>>Your long mischaracterization is not helping anybody.
Well, obviously I don't agree that it's a mischaracterization. Neither do I
agree that it is necessarily of no help to anybody. Perhaps you could
explain precisely why you think it is a mischaracterization.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 12 '08 #68
On 2008-08-12, Ben Bacarisse <be********@bsb.me.ukwrote:
Andrew Poelstra <no****@nospam.comwrites:
>On 2008-08-12, Ben Bacarisse <be********@bsb.me.ukwrote:
>>CBFalconer <cb********@yahoo.comwrites:

I assume you use it because of the simplicity of the call. You can
get that simplicity, together with safety, by using ggets.

How does ggets overcome the problem you've just identified with the
OP's use of gets?

ggets() interally allocates a dynamically-resized buffer. In the case
that it runs out of memory, it returns an appropriate error
condition.

You've snipped the "problem" so my objection has been lost. What I
was saying (and it is a bit of a wild card) is how can any routine be
safe in the presence of bit errors in the input? I don't think it is
reasonable to assume that stdio works under these conditions. We have
no reasonable method to reason about what a program does when the
input system does not deliver the input.
How would such bit errors be detected? Your input would have to have
encoded checksums or perhaps length. Giving ggets() a maximum-memory
parameter would be helpful in preventing excess memory being used in
this case, but in the general case there is no way to tell if there
are bit-level read errors in I/O.

--
Andrew Poelstra ap*******@wpsoftware.com
To email me, use the above email addresss with .com set to .net
Aug 12 '08 #69
santosh <sa*********@gmail.comwrote:
Antoninus Twink wrote:
True. The world might also be destroyed in a nuclear holocaust while
your throwaway program is reading its non-life-critical data, so why
take the risk of programming at all? Drink a beer, get laid, and wait
for the mushroom cloud to take you.
I must say, that plan beats trolling a technical newsgroup. At least it
gets you laid, which trolling prevents.
I'd use fgets even for a "throwaway" program because it's really as easy
to use and I won't have to worry about carefully deleting the sources
later.
I'd use fgets() instead of gets() all the time, simply because I have
never met a programmer incapablae of making a typo, or of dropping a
book on his keyboard.

Richard
Aug 12 '08 #70
Ben Bacarisse wrote:
....
You've snipped the "problem" so my objection has been lost. What I
was saying (and it is a bit of a wild card) is how can any routine be
safe in the presence of bit errors in the input?
By writing the routine so that, no matter what the input is, it never
has undefined behavior. This means validating all inputs before using
them in any context where an invalid value could result in undefined
behavior. The possibility of erroneous input is an unavoidable fact of
life; code which cannot deal with that fact safely is poorly designed.

What is "safely"? That is something for the designer to decide. However,
for code which is meant to be portable, "safely" is incompatible with
undefined behavior, because the designer inherently cannot have decided
what that behavior will be. For code which is, as a matter of deliberate
intent, portable only to a limited range of implementations, code with
behavior which is undefined by the standard can still count as "safe",
so long as the behavior of that code is defined by all of the
implementations it is supposed to be portable to.
... I don't think it is
reasonable to assume that stdio works under these conditions. We have
no reasonable method to reason about what a program does when the
input system does not deliver the input.
I think you're going overboard by assuming that a single corrupted bit
in an input necessarily renders the entire system untrustworthy.
Hardware can fail, and the failure is not always detectable. A single
undetected failure in the hardware associated with a disk drive or in
the network connection to an NFS mounted drive does not, in general,
justify assuming that any other component of the system has failed. It
doesn't even justify automatically assuming that there will be a
catastrophic failure of the component that was malfunctioning (though
that is certainly a possibility to consider). In particular, it doesn't
justify assuming that the routines declared in <stdio.hare defective.
Aug 12 '08 #71
Richard Heathfield <rj*@see.sig.invalidwrites:
CBFalconer said:
>Richard Heathfield wrote:
>>>
... snip ...
>>>
Again, I stress that there is no shame in an input routine not
detecting bit errors of this kind. But ggets was offered, by its
author, as a solution to the problem of a one bit error in
reading a '\n' - and it is no such thing.

No I didn't.

Then I am at a loss to explain your previous response.
>It is a solution to having such an error blow up your machine.

Perhaps you could explain how such an error could blow up one's machine in
the first place.
[...]

Suppose a program reads input using gets(). Suppose the programmer is
confident that no input line can be longer than 80 characters, but a
one-bit error reading a '\n' character causes two lines to be merged,
overflowing the input buffer.

Nothing in C can prevent or correct such an error, but just about
anything other than gets() (including ggets(), fgets(), or any of a
number of other routines) can avoid having it cause a buffer overflow.

The hypothetical one-bit error is just one example of a longer than
expected input line. I suppose it was brought up because it's
something that you can't prevent even if you think you have complete
control over what appears on stdin.

Chuck's reply upthread could be read as a claim that using ggets() can
correct such an error, but I don't believe that's what he meant.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 12 '08 #72
James Kuyper <ja*********@verizon.netwrites:
Ben Bacarisse wrote:
...
>You've snipped the "problem" so my objection has been lost. What I
was saying (and it is a bit of a wild card) is how can any routine be
safe in the presence of bit errors in the input?

By writing the routine so that, no matter what the input is, it never
has undefined behavior. This means validating all inputs before using
them in any context where an invalid value could result in undefined
behavior. The possibility of erroneous input is an unavoidable fact of
life; code which cannot deal with that fact safely is poorly designed.

What is "safely"? That is something for the designer to
decide. However, for code which is meant to be portable, "safely" is
incompatible with undefined behavior, because the designer inherently
cannot have decided what that behavior will be. For code which is, as
a matter of deliberate intent, portable only to a limited range of
implementations, code with behavior which is undefined by the standard
can still count as "safe", so long as the behavior of that code is
defined by all of the implementations it is supposed to be portable
to.
I agree when I have my engineering hat on. You can engineer for all
sorts of probable errors, but...
>... I don't think it is
reasonable to assume that stdio works under these conditions. We have
no reasonable method to reason about what a program does when the
input system does not deliver the input.

I think you're going overboard by assuming that a single corrupted bit
in an input necessarily renders the entire system
untrustworthy.
I am only pointing out an apparent conflict. CBFalconer seems to be a
"that is UB -- all bets are off" sort of a poster. I am deliberately
going overboard because I can't see how such a person can claim any
behaviour if the stdio library is not behaving as per the spec.
Hardware can fail, and the failure is not always
detectable. A single undetected failure in the hardware associated
with a disk drive or in the network connection to an NFS mounted drive
does not, in general, justify assuming that any other component of the
system has failed. It doesn't even justify automatically assuming that
there will be a catastrophic failure of the component that was
malfunctioning (though that is certainly a possibility to
consider). In particular, it doesn't justify assuming that the
routines declared in <stdio.hare defective.
Very reasonable, and I agree. I would not have said a word if ggets
was designed with system safety in mind the face of mysterious IO
failings, but it is not. It is better at handling some failures but
for others it will exhaust system resources. I've never seen a \n get
miss-read (I am sure it can happen, I am just saying that it has not
yet happened to me, to my knowledge) but I have seen drivers that just
endlessly return blocks of zeros when they fails to detect a file's
end point. ggets will just keep slurping them so while its behaviour
may remain defined, it is not particularly well engineered for failing
IO systems.

It was not my intent to put down ggets, only to point out what seemed
to be to be a very selective idea of when a program's behaviour is
formally defined and the sort of failures that ggets can cope with.

--
Ben.
Aug 12 '08 #73
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>CBFalconer said:
>>Richard Heathfield wrote:

... snip ...

Again, I stress that there is no shame in an input routine not
detecting bit errors of this kind. But ggets was offered, by its
author, as a solution to the problem of a one bit error in
reading a '\n' - and it is no such thing.

No I didn't.

Then I am at a loss to explain your previous response.
>>It is a solution to having such an error blow up your machine.

Perhaps you could explain how such an error could blow up one's machine
in the first place.
[...]

Suppose a program reads input using gets(). Suppose the programmer is
confident that no input line can be longer than 80 characters, but a
one-bit error reading a '\n' character causes two lines to be merged,
overflowing the input buffer.

Nothing in C can prevent or correct such an error, but just about
anything other than gets() (including ggets(), fgets(), or any of a
number of other routines) can avoid having it cause a buffer overflow.
Fine. Thank you. Could somebody please now explain how such an error could
blow up one's machine.
The hypothetical one-bit error is just one example of a longer than
expected input line. I suppose it was brought up because it's
something that you can't prevent even if you think you have complete
control over what appears on stdin.

Chuck's reply upthread could be read as a claim that using ggets() can
correct such an error, but I don't believe that's what he meant.
(Or at least detect it, if not correct it.) Yes, and that's what I thought
he meant. If he *didn't* mean that, why did he bring it up in the first
place?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 12 '08 #74
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
[...]
>Suppose a program reads input using gets(). Suppose the programmer is
confident that no input line can be longer than 80 characters, but a
one-bit error reading a '\n' character causes two lines to be merged,
overflowing the input buffer.

Nothing in C can prevent or correct such an error, but just about
anything other than gets() (including ggets(), fgets(), or any of a
number of other routines) can avoid having it cause a buffer overflow.

Fine. Thank you. Could somebody please now explain how such an error could
blow up one's machine.
gets(). Buffer overflow. Stepping on arbitrary memory. Undefined
behavior. Malware vector. Use your imagination.
>The hypothetical one-bit error is just one example of a longer than
expected input line. I suppose it was brought up because it's
something that you can't prevent even if you think you have complete
control over what appears on stdin.

Chuck's reply upthread could be read as a claim that using ggets() can
correct such an error, but I don't believe that's what he meant.

(Or at least detect it, if not correct it.) Yes, and that's what I thought
he meant. If he *didn't* mean that, why did he bring it up in the first
place?
If you're using gets() in an environment where you *think* you have
complete control over what appears on stdin, but a '\n' character is
somehow (due to a disk failure, for example) changed to something
else, your program can invoke undefined behavior. Using ggets()
rather than gets() is one way to avoid that particular problem; it
doesn't magically correct the corrupted '\n', but it does avoid the
UB.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 12 '08 #75
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>Fine. Thank you. Could somebody please now explain how such an error could
blow up one's machine.
>gets(). Buffer overflow. Stepping on arbitrary memory. Undefined
behavior. Malware vector. Use your imagination.
I think that's Richard's point: it only happens if you use your
imagination, not in real life.

-- Richard

--
Please remember to mention me / in tapes you leave behind.
Aug 12 '08 #76
On Aug 9, 5:42*pm, Julian <j...@nospam.invalidwrote:
[...] When I compile a program from our C course with a windows
compiler there is no problem but when I try to compile it with a
linux compiler it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows?
You have to be kidding me. There were BSODs being projected as images
inadvertently during the recent Beijing Olympic Games, and they are
very common occurrences on airport terminal displays. Can you even
describe to me what a Kernel Panic is? Do you know of anyone who ever
even seen one?

The gcc compiler (which is not Linux specific, BTW) is trying to give
you a warning about the use of gets(). The other compilers you are
using are not. Those other compilers are not doing you a very good
service, because this comment from gcc is correct (and it applies
regardless of which OS or compiler you are using.)
[...] Where can I download a non dangerous gets function?
Of course the standards people here probably don't even have the first
clue how to interpret this request. They don't realize that the
problem is not with you, but in fact is with them. They don't realize
that its not good enough to deprecate this function in a standard
nobody is going to follow anymore, or to issue warnings or document
something that says this is bad. They have to functionally poison
this function so *NO ATTEMPT* at making it work will ever succeed.
[...] I have never used gets before is
there undefined behavior somewhere?
Indeed there is. The mere usage of it invokes undefined behavior.
Here is a trimmed down example program from my assignment that
demonstrates the problem

#include <stdio.h>
#include <malloc.h>
You should use #include <stdlib.has it is included in all ANSI
compatible systems (malloc.h is not).
void main()
{
* * char *string;
* * printf("enter string (max 2000 chars): ");
* * fflush(stdin);
I'm not sure this makes any sense. Either way, it cannot semantically
do anything useful.
* * fflush(stdout);
This is not guaranteed to cause the printf () line to actually flush.
This only causes it to flush from the language's point of view, not
the underlying system's point of view. I would recommend just putting
a \n at the end of the prompt string and forgetting all about these
flushes.
* * string = (char *)malloc(2001);
* * if(!string) exit(1);
* * gets(string);
Remember: gets() *ALWAYS* exhibits undefined behavior. Even if it
appears to have accepted input text correctly, you have no expectation
that it has not also installed a virus on your machine or manipulated
the numbers in all your spread sheets as well or posted your passwords
to alt.scientology or turned on your webcam and posted images to
4chan. You can try to hobble along with fgets() as an alternative or
use the code given here:

http://www.azillionmonkeys.com/qed/userInput.html
* * printf("you entered: %s\n", string);
* * free(string);
* * exit(0);
}

On windows with TurboC and Lcc no error is printed. On linux with
gcc it says gets is dangerous.
Its actually the gcc linker which is giving you this message.
(Because its wrong even if invoked indirectly through some other
programming language.) The function gets() can never be used properly.
Please advise my instructor says gcc is overly pedantic.
You instructor's comments are non sequitur. More man years of work
has gone into gcc than years your instructor has lived.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Aug 12 '08 #77
In article <e3**********************************@k37g2000hsf. googlegroups.com>,
Paul Hsieh <we******@gmail.comwrote:
>Can you even
describe to me what a Kernel Panic is? Do you know of anyone who ever
even seen one?
I haven't often seen Linux kernel panics. More often the system just
becomes unresponsive and nothing works except pressing the power
button.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Aug 12 '08 #78
In article <g7***********@pc-news.cogsci.ed.ac.uk>, ri*****@cogsci.ed.ac.uk (Richard Tobin) wrote:
>In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>Fine. Thank you. Could somebody please now explain how such an error could
blow up one's machine.
>>gets(). Buffer overflow. Stepping on arbitrary memory. Undefined
behavior. Malware vector. Use your imagination.

I think that's Richard's point: it only happens if you use your
imagination, not in real life.
You mean buffer overflows are imaginary?
Aug 12 '08 #79
Doug Miller said:
In article <g7***********@pc-news.cogsci.ed.ac.uk>,
ri*****@cogsci.ed.ac.uk (Richard Tobin) wrote:
>>In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>>Fine. Thank you. Could somebody please now explain how such an error
could blow up one's machine.
>>>gets(). Buffer overflow. Stepping on arbitrary memory. Undefined
behavior. Malware vector. Use your imagination.

I think that's Richard's point: it only happens if you use your
imagination, not in real life.

You mean buffer overflows are imaginary?
No - but it's tricky to see how a buffer overflow can cause a machine to
blow up unless you've gone to the trouble of installing some kind of
peripheral device that contains something along the lines of Semtex.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 12 '08 #80
On Aug 12, 2:57 pm, CBFalconer <cbfalco...@yahoo.comwrote:
vipps...@gmail.com wrote:
CBFalconer <cbfalco...@yahoo.comwrote:
James Dow Allen wrote:
>Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during the
build (although I'm sure the pedants would prefer that each of
the several hundred thousand gets()'s produced its own such
message. :-)
They're all dangerous. For example, a one bit error in reading a
'\n' from your prewritten data can blow everything.
What is this one bit error you are talking about?

Who cares? With the error the '\n' is no longer a '\n', and thus
the line is not ended, and gets can happily overwrite
who-knows-what with whatever.
That 'bit error' thing is total bullshit, it can't happend, because of
the defined behavior of getc.
If *ANY* error happends with getc reading a byte, it *WILL* set the
error flag.
gets will return NULL, and the error flag will be set.

Don't post nonsense. I wasted my time thinking about this too hard.
If you are talking about hardware errors, they are not relevant to
comp.lang.c or ISO C. There are no hardware errors.
Aug 12 '08 #81
In article <fI******************************@bt.com>, rj*@see.sig.invalid wrote:
>Doug Miller said:
>In article <g7***********@pc-news.cogsci.ed.ac.uk>,
ri*****@cogsci.ed.ac.uk (Richard Tobin) wrote:
>>>In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:

Fine. Thank you. Could somebody please now explain how such an error
could blow up one's machine.

gets(). Buffer overflow. Stepping on arbitrary memory. Undefined
behavior. Malware vector. Use your imagination.

I think that's Richard's point: it only happens if you use your
imagination, not in real life.

You mean buffer overflows are imaginary?

No - but it's tricky to see how a buffer overflow can cause a machine to
blow up unless you've gone to the trouble of installing some kind of
peripheral device that contains something along the lines of Semtex.
Seems you read the phrase "blow up" a bit more literally than I did...
Aug 12 '08 #82
vipps...@gmail.com wrote:
....
That 'bit error' thing is total bullshit, it can't happend, because of
the defined behavior of getc.
If *ANY* error happends with getc reading a byte, it *WILL* set the
error flag.
gets will return NULL, and the error flag will be set.

Don't post nonsense. I wasted my time thinking about this too hard.
If you are talking about hardware errors, they are not relevant to
comp.lang.c or ISO C. There are no hardware errors.
Hardware errors are extremely relevant to whether or not ISO C's
specification for gets() is a bad design. The standard describes the
behavior of C code in terms of an abstract machine, but that's just
because the committee does not wish to tie C too closely to any
particular kind of machine architecture. It doesn't mean that the
characteristics of real machines are irrelevant to how the C language
and library should be designed. Hardware errors are an unavoidable
fact of life for all real platforms for C implementations, and also
for all plausible future platforms.

Good defensive coding practices for coping with the real possibility
of hardware errors is entirely on-topic in this newsgroup, so long as
the discussion doesn't get too bogged down into the details of
particular kinds of hardware.

And of course, in real life, as opposed to the fantasy world of gets()
defenders, hardware errors are far from being the only possible reason
why the standard input to your program might not have the format or
contents that you expected when you wrote it.
Aug 12 '08 #83
Richard Heathfield wrote:
Doug Miller said:
>ri*****@cogsci.ed.ac.uk (Richard Tobin) wrote:
>>Keith Thompson <ks***@mib.orgwrote:

Fine. Thank you. Could somebody please now explain how such
an error could blow up one's machine.

gets(). Buffer overflow. Stepping on arbitrary memory.
Undefined behavior. Malware vector. Use your imagination.

I think that's Richard's point: it only happens if you use your
imagination, not in real life.

You mean buffer overflows are imaginary?

No - but it's tricky to see how a buffer overflow can cause a
machine to blow up unless you've gone to the trouble of
installing some kind of peripheral device that contains
something along the lines of Semtex.
If the buffer is in the stack (which the C system may not have) it
allows rewriting the return address etc. This can turn machine
control over to anything at all, random or contrived. Enjoy.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 13 '08 #84
vi******@gmail.com wrote:
CBFalconer <cbfalco...@yahoo.comwrote:
>vipps...@gmail.com wrote:
>>CBFalconer <cbfalco...@yahoo.comwrote:
James Dow Allen wrote:

Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of them are
"dangerous". I live with a few "dangerous" messages during
the build (although I'm sure the pedants would prefer that
each of the several hundred thousand gets()'s produced its
own such message. :-)

They're all dangerous. For example, a one bit error in
reading a '\n' from your prewritten data can blow everything.

What is this one bit error you are talking about?

Who cares? With the error the '\n' is no longer a '\n', and
thus the line is not ended, and gets can happily overwrite
who-knows-what with whatever.

That 'bit error' thing is total bullshit, it can't happend,
because of the defined behavior of getc. If *ANY* error
happends with getc reading a byte, it *WILL* set the error
flag. gets will return NULL, and the error flag will be set.
You are highly confused. Even if you assume individual chars are
parity protected, there can be two bit errors. I think you have
never dealt with real hardware.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 13 '08 #85
ri*****@cogsci.ed.ac.uk (Richard Tobin) wrote:
Keith Thompson <ks***@mib.orgwrote:
Fine. Thank you. Could somebody please now explain how such an error could
blow up one's machine.
gets(). Buffer overflow. Stepping on arbitrary memory. Undefined
behavior. Malware vector. Use your imagination.

I think that's Richard's point: it only happens if you use your
imagination, not in real life.
If you read "blow up" as "explode physically and violently", yes; but
only Jesuits would read it as such. "Blow up" can, in computer terms,
also mean many other kinds of abrupt erroneous behaviour, from physical
but non-violent failure (no longer likely, but a real possibility in
several systems in the past - and even today, what happens if malware
causes your hard drive to pattern-seek? I haven't tried, and am not
about to), to fatal hard drive corruption, to a spectacular but
temporary crash.

Richard
Aug 13 '08 #86
CBFalconer said:
Richard Heathfield wrote:
>Doug Miller said:
>>ri*****@cogsci.ed.ac.uk (Richard Tobin) wrote:
Keith Thompson <ks***@mib.orgwrote:

>Fine. Thank you. Could somebody please now explain how such
>an error could blow up one's machine.
>
gets(). Buffer overflow. Stepping on arbitrary memory.
Undefined behavior. Malware vector. Use your imagination.

I think that's Richard's point: it only happens if you use your
imagination, not in real life.

You mean buffer overflows are imaginary?

No - but it's tricky to see how a buffer overflow can cause a
machine to blow up unless you've gone to the trouble of
installing some kind of peripheral device that contains
something along the lines of Semtex.

If the buffer is in the stack (which the C system may not have) it
allows rewriting the return address etc. This can turn machine
control over to anything at all, random or contrived. Enjoy.
Still hard to see how it's going to explode.

But it seems to me that the argument you are making, such as it is, is
merely an argument *against* gets (which is fine, and I understand it
completely), but you put it as an argument *for* ggets, and I still don't
see why that is so. It is just as much an argument for fgets, fgetline,
getsm, getline, and get_line - or anything else that refuses to overwrite
a buffer. Why ggets specifically?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 13 '08 #87
Paul Hsieh said:

<snip>
I'm sure you could peg me as the worst of the gets "pedants" though I
don't post much here any more. Richard Heathfield takes a strong
principled position against it, but he only scratches the surface of
what is obvious about gets(), then invokes his judgmental nature to
say its evil.
It is possible that I have said it's evil, but I'm failing to find a quote.
What I *am* finding is lots of quotes from other people saying it's evil.
Please check your facts before posting in future.

I've assumed that the rest of your article is about as accurate as that
paragraph, so I didn't consider it worth reading.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 13 '08 #88
On Aug 10, 1:42*am, Julian <j...@nospam.invalidwrote:
a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.
In C lots of things are dangerous. Simply assigning to an array
element is dangerous because you can easily write outside the array.

But gets() has been singled out -- by this compiler -- because you
can't make it safe by putting in extra tests for example. Other
compilers are obsessed about other things.

--
Bartc
Aug 13 '08 #89

"Richard Heathfield" <rj*@see.sig.invalidschreef in bericht
news:r7******************************@bt.com...
>I'm sure you could peg me as the worst of the gets "pedants" though I
don't post much here any more. Richard Heathfield takes a strong
principled position against it, but he only scratches the surface of
what is obvious about gets(), then invokes his judgmental nature to
say its evil.

It is possible that I have said it's evil, but I'm failing to find a
quote.
What I *am* finding is lots of quotes from other people saying it's evil.
Please check your facts before posting in future.
he wasnt quoting you and you admit you couldve said it so his remark about
judgmental nature is correct

Aug 13 '08 #90
Richard Heathfield wrote:
Paul Hsieh said:

<snip>
I'm sure you could peg me as the worst of the gets "pedants" though I
don't post much here any more. Richard Heathfield takes a strong
principled position against it, but he only scratches the surface of
what is obvious about gets(), then invokes his judgmental nature to
say its evil.

It is possible that I have said it's evil, but I'm failing to find a quote.
Here's every relevant quote from you that I could find using Google:

1999-04-14:
probably the most evil function in the standard library (except for gets, of
1999-04-27:
scanf may well be evil, but gets is positively diabolical. Stick to fgets.
1999-04-30:
will not protect your buffer. gets is - well, I disagree with those who say
it's evil because that's rather silly anthropomorphism. But I would agree
1999-07-28:
scanf is evil, remember? Not quite as evil as gets, but still fairly
malicious.
2005-12-24:
>Joe Wright said:
>When was it that use of gets() became widely known as evil?

1988, I think.
5 comments over more than 9 years, with two of them rejecting the
applicability of the word "evil" to gets(), and only one of them less
than 9 years old. That's not a particular strong demonstration of your
"judgmental nature". There are other demonstrations that are much more
convincing ;-)

Aug 13 '08 #91
Serve Lau said:
>
"Richard Heathfield" <rj*@see.sig.invalidschreef in bericht
news:r7******************************@bt.com...
>>I'm sure you could peg me as the worst of the gets "pedants" though I
don't post much here any more. Richard Heathfield takes a strong
principled position against it, but he only scratches the surface of
what is obvious about gets(), then invokes his judgmental nature to
say its evil.

It is possible that I have said it's evil, but I'm failing to find a
quote.
What I *am* finding is lots of quotes from other people saying it's
evil. Please check your facts before posting in future.

he wasnt quoting you and you admit you couldve said it so his remark
about judgmental nature is correct
It's easy to find the description of gets() as "evil" in articles by a
great many people (I tried, and succeeded many times over), but hard to
find it in articles by me (I tried, and failed).

This might or might not be good grounds for saying that other people are
judgemental, but it's lousy grounds for saying that I am.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 13 '08 #92
ja*********@verizon.net said:

<snip>
5 comments over more than 9 years, with two of them rejecting the
applicability of the word "evil" to gets(), and only one of them less
than 9 years old. That's not a particular strong demonstration of your
"judgmental nature".
Thank you, James.
There are other demonstrations that are much more convincing ;-)
<grinPerhaps so - but an impartial observer would also notice lots of
counter-examples.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 13 '08 #93

Chuck wrote:
They're all dangerous. For example, a one bit error
in reading a '\n' from your prewritten data can
blow everything.
I won't address Mr. Falconer's charges in the sequel,
but I *do* refer to the problem he cites, so I quote
him here lest someone accuse *me* of ingesting
the wrong kind of mushrooms.

Chuck doesn't specify what causes such byte damage.
The Russian mob? The Pentium Bug(tm)? gets() itself,
due to Trojan House sabotage by the Deprecator-in-Chief?
I'll (give Chuck the benefit of the doubt and) assume
the problem is gamma radiation.

On Aug 13, 7:44 am, Paul Hsieh wrote:
On Aug 11, 1:38 am, James Dow Allen <jd*********@yahoo.comwrote:
The fingerd->gets() exploit was not trivial.
Well by today's standards it is. ...
I know exactly how this is done and why and how it works.
Even *I* could and did write a 'fake finger' from the brief
description. In 1988 the message logs of those I knew got
the message:
You have been finger-f*cked by root
When the quick workaround (chown/chmod) was done, the message
became the slightly more mysterious (and Odyssean?)
You have been finger-f*cked by nobody
>[...] and programmers are left with the take-home
lesson: use gets() and the Russian mob will take
over your machine and the rest of the world.

Uh ... the Russian mob *does* use hackers ...
Uh ... yes. But watch the conclusion you're about to reach
and see if blind dogma is subverting rational thought.
>One doesn't have to be a gets() enthusiast to note
fingerd's special nature, and that the claim that
all gets() usage risks catastrophe is confused.
fingerd's special nature is that it used an auto buffer
to accept input and it used gets()....
No. fingerd's special nature was that stdin was directed
to a socket connected to an (untrusted) external machine.
Obviously gets()'er's in that environment deserve to have
their n*ts c** *ff. No one has implied anything different.
You managed to write several paragraphs on this subtopic
without even hinting that you understand that the gets()'s
we're "defending" are simply not subject to Russian mob
exploitations!
>I live with a few "dangerous"
messages during the build (although I'm sure the pedants
would prefer that each of the several hundred thousand
gets()'s produced its own such message. :-)
Perhaps there's a way to disable gcc's "dangerous"
message but, in keeping with the FSF philosophy, I'm
sure the cure is worse than the disease, something like
setenv I\'M_AN_UNREPENTANT_MORONIC_ASSHOLE

In what sense is removing this message worth it? Why not
just call fgets() and nail the trailing \n?
I've time to read very few Usenet groups these days.
Are many as totally devoid of humor as c.l.c?
Did anyone seriously think I was worried about the warning
message? (I *do* use a simple 'grep -v' to remove
one irrelevant gcc warning, but haven't bothered for
the friendly "dangerous" message.)

(Even in rec.puzzles, when I said I'd omitted a
smiley-face to "save bandwidth" I received an
overly-sober response about modern modem speeds!
You're the guys who like to over-generalize, but
I'm tempted to guess that if Americans had a better
sense of humor some of the recent domestic and
geopolitical crises might have been avoided.)

Another poster implied that a reason gets() is "dangerous"
is that it will disappear when the pedants take over
libc! Does anyone think any of us would have trouble
writing our own gets() when it goes missing from libc?
(This would also be a trivial way to get rid of the
"dangerous" message.) In fact, at the risk of encouraging
the mob to Repeat_The_Obvious One_More_Time I'll put a
gets implementation in the public domain right now:

/* Not tested :-) */
char *gets(char *s)
{
s = fgets(s, 1000000, stdin);
/* core-dump immediately if a cosmic ray has
* damaged the terminating LineFeed:
*/ if (s) 0[index(s, '\n')] = 0;
return s;
}

Hmmm. Surprised that the pedants don't add a string length
count to index() to deal with unterminated strings.
:-) :-) :-) :-)
I have looked at your code (on your website).
Buggy is not the right word for it.
*Narrow* is more what I would use.
"Narrow" is unclear. I'll assume you meant something
worse, but are being polite! In any event *most* of
the example programs at my website are just that:
*examples* rather than library functions intended for
immediate reuse.

I think there may be some useful ideas at my site.
For example, real-time programmers might benefit from a
glance at
http://james.fabpedigree.com/lesson9.htm#p94
but I imagine if you condescend to comment further
it will be to nitpick or to gloat when you find some
fragment still written in old-fashioned K&R C.

Recently I added functions to operate on compressed
sparse bit strings:
http://james.fabpedigree.com/sofa.c
which *is* intended as a small but useful (for some)
downloadable package. Paul (and anyone else) is welcome
to examine it and offer comments.
... like your hash table. Your program can only ever
support one of them, so its flaw is more fundamental.
I guess I've not uploaded my cuckoo hash implementation
yet, so you're referring to the hash table I introduced some
years ago under a Subject like "Reusable Source code".
To say that program "can only ever support one [hash table]"
is to ignore that its source code can be modified!
It's My Own(tm) code for My Own(tm) projects; I use
Just-In-Time Programming(tm) for My Own(tm) projects,
and have found this code easy to modify. As it turns
out, not supporting the feature you mention was the correct
Just-In-Time Programming(tm) decision, as that routine has
been superseded by my cuckoo hash implementation which
*does* support multiple users.

The "Reusable Source code" thread used the hash table source as
an example of a concept, without necessarily espousing *that
particular* source code. The point of the thread wasn't hash
tables, it was "Reusable Source Code" in the sense that
% vi hashtable.h
% $CC -c hashtable.c
% $CC application.c hashtable.o
allows more flexibility than the simple
% $CC application.c hashtable.o

As a specific example of the need for customization
(of hash table handling) I mentioned that many applications
permit a *maximum* of two bytes per entry (because essentially
all available memory must be well exploited) while most
off-the-shelf hash table handlers require a *minimum* of
eight bytes per entry for overhead! (Many of us use hash
tables for combinatorial searches or memory-efficient
graphs; these use smallish fixed-length keys, rather than
the variable-length keys usually assumed by hashlib, etc.)

But the whole point was completely lost, as Chuck reacted
defensively re his own hashlib (without ever explaining how
the user needing two bytes maximum could cope with hashlib's
eight-byte minimum), and Paul enlightened us with code in
which Paul (or his dog?) proudly allows the programmer to
replace the confusing, error-prone predicate
(! p->curr)
with an invocation of the function

int utilGenLinkedListIteratorEndReached \
(struct genLinkedListIterator * iter) {
if (iter == NULL) return -__LINE__;
return NULL == iter->curr;
}

Is this the kind of code you think I need to improve
my pedigree generator, Paul? Maybe I should train
*my* dog to come up with useful gems like

int add_two_numbers(int number1, int number2) {
return number1 + number2;
}

int add_three_numbers(int number1, int number2, \
int number3) {
return number1 + add_two_numbers(number2, number3);
}

or perhaps a better caricature of Pedantic Programming(tm)
might be:
int divide_checking_for_zero(int a, int b) {
if (b != 0)
return a / b;
else /* illegal: send an appropriate signal: */
return a / 0;
}

:-) :-)
>When I was rehired after a year to
add new support to a complete OS I wrote as a contractor
I was pleased to note that no changes had been found
necessary to my delivered code....

Can I obtain your OS and run the
Firefox browser on top of it?
Hunh? The OS performed to customer spec, which was
to do a MS-DOS lookalike on MC68000 chip. I estimated
how long it would take me (quite accurately as it turned
out), multiplied by my then-generous hourly wage and
ended up underbidding a company which probably already
had the OS on-shelf and was charging just for hand-holding.

My customer (who got exclusive rights -- I never claimed
to be a businessman) ended up selling the source to
A Very Big Company You've All Heard Of(tm) and recovering
his payment to me. (The Company's representative spent
several days on-site at my customer's examining the source
"eyes only" and concluded with a comment: "Originally I
was almost sure we'd develop our own in-house instead,
but after examining the source ... Sold!")
>The gets() deprecators aren't wrong; indeed I'll cheerfully
concede that their position is more defensible than mine!
But I'm happy to take a Devil's Advocate position to
encourage critical thinking when I see the preposterous and
dogmatic over-generalizations which become so routine in
this ng.
I'm sure you could peg me as the worst of the gets "pedants" ...
... I honestly take the position that gets() should, as a
side effect, attempt to delete the source file that
contained it the moment it is run.
With your "honestly", one is tempted to guess you might
not even be joking! If so: Wow! Words fail me.

Earlier I wrote:
>The gets() deprecators aren't wrong; indeed I'll cheerfully
concede that their position is more defensible than mine!
I'm afraid I'll have to (cheerfully) retract that concession
in your case, Paul.

As I compose this reply, I'm reading, in another window, about
present-day Internet security problems, despite the Billion$
of $$$ spent on $oftware by Micro$oft and others. Frankly,
I doubt that the problem is programmers using simple
functions to do simple things, but is more likely to be
the overly complex methods some of you seem to advocate.
For example, your whole "family tree" project ...
My Family Tree project started out when I wanted to
print our pedigree and snail-mail it to my nieces, but found
that 2 or 3 pages wouldn't be enough. After that
it ... er ... gradually got out of hand ... :-)
I confess that code would look *quite* different if
starting over or delivering it to a paying customer.

Just now I did
grep "gets(" *.c
in the tree subdirectory and was slightly surprised at how very
few there were. (The estimate of several 100,000's of gets()
*executions* was still conservative as the Index starts with
330,000 lines which are passed pipe-like to three
gets()'ing filters.)
... you did the whole thing in C didn't you?
Call it a fetish if you wish, but I *do* like to program in C.
My brain isn't completely dormant here, raising my kids and
smelling the roses: I read up on a variety of topics, e.g.
historical linguistics. Learning a new programming language
is *not* a priority and wasn't even before I retired, unless
you count LaTeX as a "programming" language.
And you chose C because ...
you think its actually tighter or something;
even though you are using
massively over-sized buffers to hold those strings.
LOL, chuckle! Call me simplistic but I process one line
at a time. The PC I use has relatively little memory,
but it's enough to spare one (1) 2000-byte buffer
for one (1) 200-byte string. :-) :-)

Moreover, your comments show another confusion: one uses
the "over-sized buffer" whether one gets()'s or fgets()'s.
In either case, if the string needs to be preserved,
one strlen()'s, malloc()'s, and strcpy()'s (*) Yes, one can
hire Chuck F. to implement this trivial functionality, but
so what? (* - or do the pedants use strncpy() instead of
strcpy() even when they've just strlen()'ed on the off-chance
a gamma-ray zapped the null terminator? :-)

True, the fgets() *can* handle lines too long to fit in
the already "over-sized" buffer, but if you're doing that
handling in more than 2% of your fgets() applications you must
be coding like a masochist! The whole point of gets()/fgets()
is the simplicity of reading exactly one line: if you lose
that, you might as well just use fread().
deal with the growing list of tree nodes? Do you painstakingly
allocate each one, then free them all?
... Even if you do it in C, you are going to
want to write a special tree node allocation pool layer
and use a string library.
You seem to have a model of what my software does which
has very little relationship to its reality. There certainly
are painful parts, but they have nothing to do with growing,
allocating, or freeing. Programming speed and reliability
depend on simplicity and you are imagining problems I've
never encountered in 'tree.'
Of course you do, you revere K&R as if they were gods.
If you've been reading my website, you're misquoting!
I revere T&R (not K&R) as if they were human, but excellent
and creative designers.
>Programming (and much real-world activity) involves
compromise between thoroughness and convenience.

Giving up on thoroughness is basically never worth it.
>Thoroughness is not wrong, *BUT YOU SHOULD SPEND YOUR
THOROUGHNESS WISELY*. The original Hubble Telescope
program spent $10,000 studying whether or not to do a
$3 Million test. Meanwhile the flaw, that showed up
post-launch, could have been found with a simple $50 test.
I'll bet some engineer would have done the $50 test
if not dizzied by the testing paperwork requirements
dictated by pedants.

That's the wrong lesson. The right lesson: the only way to catch
everything via a test, is to test everything....
I'm agnostic about whether the taxpayers should have been
required to fund the expensive test; the point is that the
flaw would have surfaced readily (with the $50 test) in a
less pedantic testing environment. You seem to have missed
this point; indeed you seem to be arguing that *no* test is
too expensive for the taxpayers! ... Where do you fit on the
political spectrum, Paul? :-)

Regarding my claim, which you contested, that one
SHOULD SPEND ONE'S THOROUGHNESS WISELY
consider again the table hander you deprecated as
single instance. Making it multi-instance *would* have
complicated it and did indeed prove unnecessary.
I once worked with a guy who added so many unnecessary
features to his software package, that it was difficult,
later, to add *useful* features he'd overlooked.

I think
SPEND ONE'S THOROUGHNESS WISELY
is a good synopsis of this whole subthread.
There's a lot of changes I'd make to the 'tree'
software if it were worth my while spending time cleaning
it up. Replacing gets() with fgets() is *definitely*
not on the list.

OP wrote, to start the thread:
Is linux more dangerous than windows?
*This* is a joke, right?
a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.
Please advise my instructor says gcc is overly pedantic.
Good question! Thanks for asking. :-)

James Hussein Allen
Aug 14 '08 #94
James Dow Allen said:
I've time to read very few Usenet groups these days.
Are many as totally devoid of humor as c.l.c?
I put as much in as I can without being silly about it. Alas, many Usanians
tend not to notice it.

clc is better than average at understanding my humour, perhaps partly
because it has a relatively high proportion of British subscribers and
partly because even the non-British subscribers are often very bright.

But *this* article contains no humour whatsoever.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 14 '08 #95
On 13 Aug, 09:05, Richard Heathfield <r...@see.sig.invalidwrote:
Paul Hsieh said:
I'm sure you could peg me as the worst of the gets "pedants" though I
don't post much here any more. *Richard Heathfield takes a strong
principled position against it, but he only scratches the surface of
what is obvious about gets(), then invokes his judgmental nature to
say its evil.

It is possible that I have said it's evil, but I'm failing to find a quote.
What I *am* finding is lots of quotes from other people saying it's evil.
Please check your facts before posting in future.

I've assumed that the rest of your article is about as accurate as that
paragraph, so I didn't consider it worth reading.
I'd recommend giving it a try. Some of it is quite interesting
(and I don't think he mentions you again).
--
Nick Keighley
Aug 14 '08 #96
On Aug 14, 3:04*pm, Richard Heathfield <r...@see.sig.invalidwrote:
James Dow Allen said:
I've time to read very few Usenet groups these days.
Are many as totally devoid of humor as c.l.c?

I put as much in as I can without being silly about it.
Alas, many Usanians tend not to notice it.
I'd have exempted *you* specifically but, since we're
on opposite sides of this debate, I was afraid I'd
risk being labeled as your sock puppet playing
"Trolling Pickle." I *did* include a specific
reference to "Americans" to limit my aspersion.
But *this* article contains no humour whatsoever.
Having read your past posts, this seems like a give-away
that there *is* some hidden humor, but I don't see
it, unless your flagrant misspelling "humour" is itself
some caprice or megrim related to the lost Empire.

James
Aug 14 '08 #97
James Dow Allen said:
On Aug 14, 3:04 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>James Dow Allen said:
I've time to read very few Usenet groups these days.
Are many as totally devoid of humor as c.l.c?

I put as much in as I can without being silly about it.
Alas, many Usanians tend not to notice it.

I'd have exempted *you* specifically but, since we're
on opposite sides of this debate, I was afraid I'd
risk being labeled as your sock puppet playing
"Trolling Pickle." I *did* include a specific
reference to "Americans" to limit my aspersion.
If I were you, I wouldn't waste any time worrying about the kind of idiot
that thinks you're a sock puppet (or indeed any kind of idiot). Life's too
short.
>But *this* article contains no humour whatsoever.

Having read your past posts, this seems like a give-away
that there *is* some hidden humor, but I don't see
it,
<sighYes, I guessed you wouldn't. Nevertheless, it is there, such as it
is. And no, I'm not going to explain. If you saw it, you saw it. If you
didn't, you didn't. And those who don't believe me are probably those who
wouldn't even believe me if I said 2+2=4, so I'm not going to try to
convince them.
unless your flagrant misspelling "humour"
At this point, I must insert an obligatory "harumph".
is itself
some caprice or megrim related to the lost Empire.
Lost? No, my dear chap, not at all - merely mislaid.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 14 '08 #98
Richard Heathfield wrote:
Alas, many Usanians tend not to notice it.
Please try not to use odd abbreviations that are not standard English.


Brian
Aug 14 '08 #99
On 14 Aug 2008 at 8:04, Richard Heathfield wrote:
James Dow Allen said:
>I've time to read very few Usenet groups these days.
Are many as totally devoid of humor as c.l.c?
No. It's one of the many ways in which clc is "special".
I put as much in as I can
Now /that's/ funny!

Aug 14 '08 #100

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

101 posts views Thread by Bill Cunningham | last post: by
4 posts views Thread by cesark | last post: by
302 posts views Thread by Lee | last post: by
10 posts views Thread by lovecreatesbea... | last post: by
6 posts views Thread by Thomas.li | last post: by
reply views Thread by Saiars | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.