scanf (yes/no) - doesn't work + deprecation errors scanf, fopen etc.

  • Thread starter =?ISO-8859-1?Q?Martin_J=F8rgensen?=
  • Start date
K

kuyper

Richard said:
It is simple enough to see the issue with it : the main issue is that
it is there and needs to remain there to support legacy code. I dont
think the standards commitee will pay for millions of lines to have
system specific handwritten gets() to replace the old one or, god
forbid, to change all the calls themselves to do boundary checks and
use something more robust.

What is the process for C to depreciate something like this? Is it a
new flag to switch it on? ....
Like a lot of buggy old stuff, the people who used it were often not so
stupid and made big enough buffers to cope with the declared range of
inputs. Perfect? No. But worked for them at the time.

The problem occurs when inputs outside the declared range are provided.
No C program has sufficient portable control over it's standard input
to guarantee that this won't happen. Of course, not all programs need
to be portable, and there are non-portable ways to obtain sufficient
control.

I don't think it's good design for a C program to ever have undefined
behavior. When given inputs that are outside it's declared range, it
should fail gracefully. By gracefully, I mean that it should provide
error message in the appropriate log file or stderr, or at least return
a checkable error status to the calling environment. Even if that's not
possible, "failing gracefully" means, as an absolute minimum, that the
behavior of the program is not undefined. It's not possible to use
gets() in a portable fashion while conforming to this guideline.
 
R

Richard G. Riley

The problem occurs when inputs outside the declared range are
provided.

I think we all realise this and it was addressed above.
No C program has sufficient portable control over it's standard input
to guarantee that this won't happen. Of course, not all programs need
to be portable, and there are non-portable ways to obtain sufficient
control.

Yes, of course.
I don't think it's good design for a C program to ever have undefined
behavior. When given inputs that are outside it's declared range, it

It is not good design for any program to have undefined behaviour : a
lot do unfortunately...
should fail gracefully. By gracefully, I mean that it should provide
error message in the appropriate log file or stderr, or at least return
a checkable error status to the calling environment. Even if that's not
possible, "failing gracefully" means, as an absolute minimum, that the
behavior of the program is not undefined. It's not possible to use
gets() in a portable fashion while conforming to this guideline.

This is not the issue I was raising. Of course it is not good to use
such a function. The issue is with maintenance of HUGE old systems
which do make a lot of use (carefully) of gets() and the like. I have
a fair degree of experience in trouble shooting such systems and
removing gets() would cause a lot of grief to a lot of people. No one
says it is nice but "its done now" as they say. A bit like C++ :-;

Hence my closing comments on compiler warnings.
 
K

Keith Thompson

Richard G. Riley said:
This is not the issue I was raising. Of course it is not good to use
such a function. The issue is with maintenance of HUGE old systems
which do make a lot of use (carefully) of gets() and the like. I have
a fair degree of experience in trouble shooting such systems and
removing gets() would cause a lot of grief to a lot of people. No one
says it is nice but "its done now" as they say. A bit like C++ :-;

gets() cannot be used carefully. (That's a little bit of an
overstatement, but only just barely.)

If gets() were removed by the standard, existing code that uses it
could easily be catered to by using the compiler in a non-standard
mode that provides it. There are plenty of non-standard functions in
most implementations (such as strdup()); there's no reason gets()
couldn't be another one.

gets() is also easy enough to implement yourself if necessary.

Having gets() in the standard is an implied endorsement of a uniquely
dangerous function. Removing it from the standard needn't cause any
significant inconvenience.
 
R

Richard G. Riley

gets() cannot be used carefully. (That's a little bit of an
overstatement, but only just barely.)

defined input from stdio. But not ideal as I was at pains to point
out. Nobody is supporting the robustness of it.
If gets() were removed by the standard, existing code that uses it
could easily be catered to by using the compiler in a non-standard
mode that provides it. There are plenty of non-standard functions
in

Agreed. And what I was suggesting with regard to special compiler options.
most implementations (such as strdup()); there's no reason gets()
couldn't be another one.

gets() is also easy enough to implement yourself if necessary.

Not necessarily on huge (distributed) codebases where you would need
to change the calling code to encompass "to be sure" buffers of the
required size for the unlikely case of 20Gb of characters being force
fed into it.
Having gets() in the standard is an implied endorsement of a uniquely
dangerous function. Removing it from the standard needn't cause any
significant inconvenience.

Other than the need to provide compiler coverage or potentially
humongous work effort to fill the gaps.

I cant immediately see any easy way to just relink in "ones own" gets
since, due to the function parameters, it can not really be any safer other
than somehow catching the out of bounds which could arise. And that in
itself might well screw up a lot of monolithic dinosaurs out there
which have happily been churning away for donkeys years.

Please be sure that I am in no way condoning gets() as a function to
use : rather I am advising caution on the decision to remove
it.
 
K

kuyper

Richard said:
provided.

I think we all realise this and it was addressed above.

I didn't get that impression. By referring to those people as "not so
stupid", you imply that the coping mechanism they used was acceptable.
That's what I was disagreeing with. If it doesn't fail gracefully when
given outputs outside it's declared range, it's not acceptable.

....
This is not the issue I was raising. Of course it is not good to use
such a function. The issue is with maintenance of HUGE old systems
which do make a lot of use (carefully) of gets() and the like. I have
a fair degree of experience in trouble shooting such systems and
removing gets() would cause a lot of grief to a lot of people. No one
says it is nice but "its done now" as they say. A bit like C++ :-;

I wasn't disagreeing with that point either. I was only responding to
your implied approval of the legacy code that used gets() "carefully".
Using gets() rather than fgets() was never the right choice, even for
code which relied on non-portable assumptions that made it safe; it may
have been an excusable bad decision in the early days of the language,
but it doesn't deserve approval.
 
D

Douglas A. Gwyn

Richard said:
I find it scary that someone this condescending can be on the Standard
committee.
...
I find it even scaries that someone who doesn't remember the Morris worm
can be on the Standard committee.

Who's being condescending? I was one of the people who
captured and analyzed the Morris worm at the time. I've
been involved with information security for more than
30 years. Perhaps you should try to understand my point
rather than rejecting it a priori.
 
D

Douglas A. Gwyn

Richard G. Riley said:
What is the process for C to depreciate something like this? Is it a
new flag to switch it on?

The usual standards mechanism is for a newly issued revision
of the standard to flag the item as a "deprecated feature",
which means that it must still be supported by conforming
implementations at least until the next major revision of
the standard. That typically means 10 years at least before
implementations need to do anything differently. It would
be likely that most implementations would continue to include
the function in their library (since it is needed to link
with existing objects), merely disabling the automatic
declaration obtained when the header is #included. It is
by no means obvious that that would benefit anyone.
 
D

Douglas A. Gwyn

Richard said:
True. But it's a start. As long as gets() has the official OK of the
Standard, the kind of newbie programmer who doesn't look beyond what he
was taught will see that It Is Official, Therefore It Is Good.

If they don't think any more clearly than that,
gets() is the least of their worries. The standard
doesn't cater to sloppy programmers, nor should it.
 
J

Jordan Abel

The usual standards mechanism is for a newly issued revision
of the standard to flag the item as a "deprecated feature",
which means that it must still be supported by conforming
implementations at least until the next major revision of
the standard. That typically means 10 years at least before
implementations need to do anything differently. It would
be likely that most implementations would continue to include
the function in their library (since it is needed to link
with existing objects), merely disabling the automatic
declaration obtained when the header is #included. It is
by no means obvious that that would benefit anyone.

How about making attempted use of gets() a required diagnostic?

or changing the standard to allow gets() to print an
implementation-defined string to stderr before accepting input
 
K

Keith Thompson

Richard G. Riley said:
Not necessarily on huge (distributed) codebases where you would need
to change the calling code to encompass "to be sure" buffers of the
required size for the unlikely case of 20Gb of characters being force
fed into it.

I don't understand your point here. If gets() is removed from the
standard, it can still be provided by the library. If gets() is
removed from the library, an exactly equivalent function with the same
name would be trivial to write. This replacement would be exactly as
useful, and exactly as dangerous, as the current standard gets().

If replacing all calls to gets() by calls to a safer alternative is
too much effort, *you don't have to do it*.

[snip]
Please be sure that I am in no way condoning gets() as a function to
use : rather I am advising caution on the decision to remove
it.

I don't believe that removing it from the standard would cause any
harm in the real world.
 
K

Keith Thompson

Douglas A. Gwyn said:
Who's being condescending? I was one of the people who
captured and analyzed the Morris worm at the time. I've
been involved with information security for more than
30 years. Perhaps you should try to understand my point
rather than rejecting it a priori.

I can't speak for anyone else, but I haven't rejected your point a
priori. I've rejected your point after careful consideration.
 
K

Keith Thompson

Douglas A. Gwyn said:
If they don't think any more clearly than that,
gets() is the least of their worries. The standard
doesn't cater to sloppy programmers, nor should it.

The standard caters to sloppy programmers by providing the gets()
function. It shouldn't.
 
M

Micah Cowan

Richard G. Riley said:
It is simple enough to see the issue with it : the main issue is that
it is there and needs to remain there to support legacy code. I dont
think the standards commitee will pay for millions of lines to have
system specific handwritten gets() to replace the old one or, god
forbid, to change all the calls themselves to do boundary checks and
use something more robust.

Removing it before deprecation would be mean. Deprecating it, and then
removing it sometime later, would be a very good idea. Keeping in
mind, too, that conforming implementations can still provide access to
the function through the usual means of extending C.

Also, legacy code that actually uses gets() is very likely to use
implementations of previous C standards, rather than implementations
of more current ones. Seems to me, anyway.
 
M

Micah Cowan

Wojtek Lerch said:
But of course it can: you just need to be careful when using a program that
calls gets().

That's perfectly alright if you're certain to be the only user of your
program, ever. Simple, quick test progs might be alright.

Anything else, you're asking for trouble. I would never dream of
making such a program accessible from the 'Net in any way, or
available to other users on a system I cared to keep.

-Micah
 
K

kuyper

Richard said:
defined input from stdio.

Relying upon defined input from stdio in order to avoid producing
undefined behavior does not qualify as careful. It counts as sloppy.
Not necessarily on huge (distributed) codebases where you would need
to change the calling code to encompass "to be sure" buffers of the
required size for the unlikely case of 20Gb of characters being force
fed into it.

I believe he's talking about providing your own gets() replacement,
with behavior identical to that of the gets() currently provided by the
standard library. This would require changing all of the gets() calls
to refer to the replacement, #inclusion of the appropriate non-standard
header in each source code file where that replacement is needed: it's
simple enough that it could probably be safely automated. Of course,
the non-standard file should contain something like the following:

#ifndef BUFFER_OVERRUNS_INVITED
#error Use of mygets() allows buffer overruns.
#endif

The required #define of BUFFER_OVERRUNS_INVITED would help document the
danger you've decided is worth living with.

No matter what happens, increased safety for code that uses gets()
requires source code re-writes that are hard to automate. If you've got
a sufficiently strong need for increased safety to justify such
re-writes, you don't need your own user-defined replacement for the
standard gets(), just replace all of the gets() calls with fgets()
calls.
I cant immediately see any easy way to just relink in "ones own" gets
since, due to the function parameters, it can not really be any safer other
than somehow catching the out of bounds which could arise. And that in

Defining your own replacement for gets() isn't for increased safety,
it's to allow your old, unsafe code to continue to be buildable with
exactly the same lack of safety, even if gets() is no longer part of
the standard library.
 
M

Micah Cowan

Douglas A. Gwyn said:
If they don't think any more clearly than that,
gets() is the least of their worries. The standard
doesn't cater to sloppy programmers, nor should it.

Nor could it, without changing the language entire. However, if we sum
up the points that have been made:

1. gets() is virtually impossible to use safely.
2. Deprecating it would serve as a warning to would-be users.
3. Deprecating and later removing it would likely not produce
any notable effect in the real world for some time.
4. But it hopefully would eventually.

So essentially, your arguments, AIUI, have been that it would only do
a little good. But, I think most of us lurkers at clc are saying:
"little good is better than nothing". And I haven't heard any actual
arguments from you as to why we should not do it, only why doing it
would not amount to much. (I'm discounting your comparison of it with
other unsafe functions that may still be used safely under some
conditions.)

-Micah
 
F

Flash Gordon

Keith said:
I can't speak for anyone else, but I haven't rejected your point a
priori. I've rejected your point after careful consideration.

Same here. Including after noting and commenting on in this thread the
fact that the more harmless implicit int *has* been removed from the
standard and this has not suddenly rendered millions of lines of code
using it unusable.

If anyone thinks removing implicit int was a good thing because it adds
a requirement for using a function without a declaration in scope, there
was a more direct way the same result could have been achieved. Adding a
requirement that there be a declaration in scope.

If it take 5 years to get it deprecated and another 10 years to get it
removed it is *still* worth starting the process. If the process is not
started it will *never* finish.

If removing it is truly such a scary prospect (and I've yet to see an
argument for that which I consider to be strong) then as someone else
stated mandating that a diagnostic be produced for it's use would be a
start.
--
Flash Gordon
Living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidlines and intro -
http://clc-wiki.net/wiki/Intro_to_clc
 
P

pete

Douglas said:
The standard
doesn't cater to sloppy programmers, nor should it.

It shouldn't, but it does.

%lf now allowed for doubles with printf.
return statement no longer required in main.
 
J

Jordan Abel

That's perfectly alright if you're certain to be the only user of your
program, ever. Simple, quick test progs might be alright.

Anything else, you're asking for trouble. I would never dream of
making such a program accessible from the 'Net in any way, or
available to other users on a system I cared to keep.

On most systems that would only be a danger if the code is running with
rights that you don't want the other users / internet users to be able
to gain access to. You certainly can't get root from a non-setuid
program.
 

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,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top