Why "gets" has not been deprecated yet?

Discussion in 'C++' started by Marcus, Nov 2, 2005.

  1. Marcus

    Marcus Guest

    We all know that the "gets" function from the Standard C Library (which
    is part of the Standard C++ Library) is dangerous. It provides no
    bounds check, so it's easy to overwrite memory when using it, and
    impossible to guarantee that it won't happen.

    Therefore, i think it's surprising that this function has not been
    deprecated.
    The C++98 Standard keeps it from the C89 standard.
    The C99 Standard has kept it :-o.

    Now, the C standard committee is working on safe functions (the ones
    that end with "_s") for the C Standard Library. I don't know if they
    are going to deprecate the dreaded "gets". Even if not, i think it
    would be a good idea to deprecate it in the next C++ standard, since
    C++ has better ways to accomplish the same task (getline). It's too
    early to expect the safe functions (*_s) in the C++ Standard, but
    getting rid of "gets" is not that hard, isn't it? Programs that use it
    are broken anyway. Also, C++ has deprecated other features from C just
    because C++ has better alternatives (static meaning "internal linkage"
    and headers ending in ".h").

    Opinions? Should this message be posted on comp.std.c++?
     
    Marcus, Nov 2, 2005
    #1
    1. Advertising

  2. Marcus wrote:
    > Opinions? Should this message be posted on comp.std.c++?


    You probably want to post it over there, as people on here generally
    focus more on application, and less on changing / debating the
    standard.

    Be careful with the assumption that all things using gets are
    inherantly flawed however. =P
     
    Josh Mcfarlane, Nov 3, 2005
    #2
    1. Advertising

  3. Rolf Magnus wrote:
    > Well, gets invokes undefined behavior.


    >From a buffer overrun? If not, what else causes the undefined behavior?
     
    Josh Mcfarlane, Nov 3, 2005
    #3
  4. Marcus

    Ron Natalie Guest

    Josh Mcfarlane wrote:
    > Rolf Magnus wrote:
    >> Well, gets invokes undefined behavior.

    >
    >>From a buffer overrun? If not, what else causes the undefined behavior?

    >

    Many functions in the C library have undefined behavior when given
    arguments outside their range. They are by and large a piece of
    inherited crap that should have never received standard status (the
    STDIO part of the library is the most misdesigned malodious thing
    ever foisted on the community, it was derived from a misnamed
    piece of crap from an ancient UNIX project called the "portable
    IO library").
     
    Ron Natalie, Nov 3, 2005
    #4
  5. Ron Natalie wrote:
    > Many functions in the C library have undefined behavior when given
    > arguments outside their range. They are by and large a piece of
    > inherited crap that should have never received standard status (the
    > STDIO part of the library is the most misdesigned malodious thing
    > ever foisted on the community, it was derived from a misnamed
    > piece of crap from an ancient UNIX project called the "portable
    > IO library").


    Well, ya, my point was, if you can confine to arguments within their
    range, they do function (at least to my knowledge). Good? No, but still
    functionable.

    Anywho, let's go throw this at the std people and see if it can get any
    support.
     
    Josh Mcfarlane, Nov 3, 2005
    #5
  6. Marcus

    Gaijinco Guest

    > Many functions in the C library have undefined behavior when given
    > arguments outside their range. They are by and large a piece of
    > inherited crap that should have never received standard status (the
    > STDIO part of the library is the most misdesigned malodious thing
    > ever foisted on the community, it was derived from a misnamed
    > piece of crap from an ancient UNIX project called the "portable
    > IO library").


    Wow! I had never hear about that, can you explain a little more what
    are the problems of <stdio.h>?
     
    Gaijinco, Nov 3, 2005
    #6
  7. Marcus

    Rolf Magnus Guest

    Josh Mcfarlane wrote:

    > Be careful with the assumption that all things using gets are
    > inherantly flawed however. =P


    Well, gets invokes undefined behavior.
     
    Rolf Magnus, Nov 3, 2005
    #7
  8. Marcus

    Ron Natalie Guest

    Gaijinco wrote:
    >> Many functions in the C library have undefined behavior when given
    >> arguments outside their range. They are by and large a piece of
    >> inherited crap that should have never received standard status (the
    >> STDIO part of the library is the most misdesigned malodious thing
    >> ever foisted on the community, it was derived from a misnamed
    >> piece of crap from an ancient UNIX project called the "portable
    >> IO library").

    >
    > Wow! I had never hear about that, can you explain a little more what
    > are the problems of <stdio.h>?
    >

    Functions like gets that have no provisions for safety.
    All the functions have arguments in different order. Some
    of them have the file stream arg first, some last.
    fwrite/fread have a number of records and record size number
    that nobody knows what to do with other than multiply together.
    It just goes on from their, the library is crap.
     
    Ron Natalie, Nov 3, 2005
    #8
  9. Marcus

    Guest

    This propensity for undefined behaviour is an example of Design by
    Contract (DbC): you meet the preconditions, and you get the contracted
    behaviour. The philosophy says: if you stuff up, and fail to pick it
    up in your testing, it's your fault and you're a pathetic excuse for a
    programmer, (and probably a human being). Anyway, the point is that
    DbC can work, but you have to guarantee the preconditions. For gets,
    they're extreme: if you know that standard input necessarily sends
    lines below a certain length, then you can use it. This is probably
    only the case when standard input is coming from some other source that
    you control. For example, you might write a filter that works on some
    fixed-length records, and is designed to be used in a pipeline ala
    (UNIX) "cat file | filter" or (DOS) "type file | filter". Who's to say
    that you don't know what you're doing well enough to guarantee the line
    length precondition? It's your own call whether you use it.

    FWIW, I dislike DbC and agree that gets should hardly ever be used,
    would happily consider that it should never be used in new code, but
    wouldn't go to the extent of saying that it must never be used and it's
    worth breaking existing code using it. More generally, the stdio
    library has proven itself a well-designed bit of work, in that while
    it's error-proneness been the cause of innumerable errors, it's
    concision, usability and flexibility has supported innumerable systems
    that do useful work. If you think you can write better in C, go ahead
    and see if anyone wants to use your creations.... One of the
    compromises of C++ is that it should overwhelmingly be a superset of C,
    with benefits in porting, skills transfer etc..

    Tony
     
    , Nov 3, 2005
    #9
  10. Marcus

    Rolf Magnus Guest

    Josh Mcfarlane wrote:

    > Ron Natalie wrote:
    >> Many functions in the C library have undefined behavior when given
    >> arguments outside their range. They are by and large a piece of
    >> inherited crap that should have never received standard status (the
    >> STDIO part of the library is the most misdesigned malodious thing
    >> ever foisted on the community, it was derived from a misnamed
    >> piece of crap from an ancient UNIX project called the "portable
    >> IO library").

    >
    > Well, ya, my point was, if you can confine to arguments within their
    > range, they do function (at least to my knowledge). Good? No, but still
    > functionable.


    The problem about gets is that there is no way for the program to provide
    arguments that are really 100% safe. gets will produce a buffer overflow if
    the buffer you provided isn't large enough for the incoming data. There is
    no (portable) way to make the buffer big enough in every case, since the
    program can't control the amount of data that is read. This lack of control
    leads me to the conclusion that gets() can be seen as generally invoking
    undefined behavior.
     
    Rolf Magnus, Nov 3, 2005
    #10
  11. Marcus

    Pete Becker Guest

    Rolf Magnus wrote:
    >
    > The problem about gets is that there is no way for the program to provide
    > arguments that are really 100% safe. gets will produce a buffer overflow if
    > the buffer you provided isn't large enough for the incoming data. There is
    > no (portable) way to make the buffer big enough in every case, since the
    > program can't control the amount of data that is read. This lack of control
    > leads me to the conclusion that gets() can be seen as generally invoking
    > undefined behavior.
    >


    That's too broad. The behavior of gets is undefined if the input in fact
    is too large for the buffer. If it isn't, the behavior is well defined.

    That's not a comment on its utility, but on how to apply technical terms.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Nov 3, 2005
    #11
  12. Marcus

    Neil Cerutti Guest

    On 2005-11-03,
    <> wrote:
    > This propensity for undefined behaviour is an example of Design
    > by Contract (DbC): you meet the preconditions, and you get the
    > contracted behaviour. The philosophy says: if you stuff up,
    > and fail to pick it up in your testing, it's your fault and
    > you're a pathetic excuse for a programmer, (and probably a
    > human being). Anyway, the point is that DbC can work, but you
    > have to guarantee the preconditions. For gets, they're
    > extreme: if you know that standard input necessarily sends
    > lines below a certain length, then you can use it. This is
    > probably only the case when standard input is coming from some
    > other source that you control. For example, you might write a
    > filter that works on some fixed-length records, and is designed
    > to be used in a pipeline ala (UNIX) "cat file | filter" or
    > (DOS) "type file | filter". Who's to say that you don't know
    > what you're doing well enough to guarantee the line length
    > precondition?


    Crackers.

    --
    Neil Cerutti
     
    Neil Cerutti, Nov 3, 2005
    #12
  13. Marcus

    Ian Malone Guest

    Ron Natalie wrote:

    > fwrite/fread have a number of records and record size number
    > that nobody knows what to do with other than multiply together.
    > It just goes on from their, the library is crap.


    fwrite and fread return the number of objects written or read,
    not the number of chars. But in general you may as well
    use <iostream> and friends.

    --
    imalone
     
    Ian Malone, Nov 3, 2005
    #13
  14. Marcus

    Guest

    Consider: someone writes two programs that share a header file
    containing a buffer-size constant. In one program, lines are generated
    and checked against this maximum length. The other program defines a
    buffer based on this length, but uses gets(). The two programs may be
    reasonably well synchronised, in that a change to the header triggers
    rebuilds of both. Just hope they're distributed together too! This is
    arguably in line with a workable (but deeply unappealing to me) DbC
    philosophy. I can't say it's crackers, even though I'd like to be able
    to! - Tony
     
    , Nov 3, 2005
    #14
  15. Marcus

    Ron Natalie Guest

    Ian Malone wrote:
    > Ron Natalie wrote:
    >
    >> fwrite/fread have a number of records and record size number
    >> that nobody knows what to do with other than multiply together.
    >> It just goes on from their, the library is crap.

    >
    > fwrite and fread return the number of objects written or read,
    > not the number of chars. But in general you may as well
    > use <iostream> and friends.
    >

    Yeah, so? But there is no concept of reading anything other
    than char's from the stream. All the function does is multiply
    those two args togehter and divides by the size on return.
    It's a stupid design.
     
    Ron Natalie, Nov 3, 2005
    #15
  16. Marcus

    Pete Becker Guest

    Rolf Magnus wrote:
    >
    > Ok, let's apply technical terms then:
    > According to the C++ standard, UB is "behavior, such as might arise upon use
    > of an erronous program construct or erroneous data, for which this
    > International Standard imposes no requirements". Applying that to your
    > sentence above, that means that my program has "an erronous program
    > construct or erroneous data", if the input is too large and is correct if
    > the input fits in the provided space. But my program can't control whenther
    > the input fits or not. It can control the size of the buffer, but not the
    > amount of data coming in, so it doesn't have any way of ensuring the
    > well-defined behavior that you are writing about.


    That's correct.

    > It's as if you say "the behavior is well-defined only on full moon".
    >


    No, it's not. Not being able to control input is not the same as input
    always being ill-formed. For a quick and dirty one-off command line
    utility I'd have no qualms about using gets.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Nov 3, 2005
    #16
  17. Marcus

    Rolf Magnus Guest

    Pete Becker wrote:

    > Rolf Magnus wrote:
    >>
    >> The problem about gets is that there is no way for the program to provide
    >> arguments that are really 100% safe. gets will produce a buffer overflow
    >> if the buffer you provided isn't large enough for the incoming data.
    >> There is no (portable) way to make the buffer big enough in every case,
    >> since the program can't control the amount of data that is read. This
    >> lack of control leads me to the conclusion that gets() can be seen as
    >> generally invoking undefined behavior.

    >
    > That's too broad. The behavior of gets is undefined if the input in fact
    > is too large for the buffer. If it isn't, the behavior is well defined.


    However, the C++ standard does not specify how large the input is or may be,
    and there is no way for the program to know it, so the "if it isn't, the
    behavior is well defined" part is of no relevance for my program. I must
    assume that the input may be too large, no matter what my program does.

    > That's not a comment on its utility, but on how to apply technical terms.


    Ok, let's apply technical terms then:
    According to the C++ standard, UB is "behavior, such as might arise upon use
    of an erronous program construct or erroneous data, for which this
    International Standard imposes no requirements". Applying that to your
    sentence above, that means that my program has "an erronous program
    construct or erroneous data", if the input is too large and is correct if
    the input fits in the provided space. But my program can't control whenther
    the input fits or not. It can control the size of the buffer, but not the
    amount of data coming in, so it doesn't have any way of ensuring the
    well-defined behavior that you are writing about.
    It's as if you say "the behavior is well-defined only on full moon".
     
    Rolf Magnus, Nov 3, 2005
    #17
  18. Marcus

    Mike Wahler Guest

    <> wrote in message
    news:...
    > This propensity for undefined behaviour is an example of Design by
    > Contract (DbC): you meet the preconditions, and you get the contracted
    > behaviour. The philosophy says: if you stuff up, and fail to pick it
    > up in your testing, it's your fault and you're a pathetic excuse for a
    > programmer, (and probably a human being). Anyway, the point is that
    > DbC can work, but you have to guarantee the preconditions. For gets,
    > they're extreme: if you know that standard input necessarily sends
    > lines below a certain length, then you can use it. This is probably
    > only the case when standard input is coming from some other source that
    > you control. For example, you might write a filter that works on some
    > fixed-length records, and is designed to be used in a pipeline ala
    > (UNIX) "cat file | filter" or (DOS) "type file | filter". Who's to say
    > that you don't know what you're doing well enough to guarantee the line
    > length precondition? It's your own call whether you use it.


    Who's to say that an input stream with a 'guaranteed' limit of
    'record size', did not get corrupted by some outside influence,
    rendering the 'guarantee' spurious? I've actually had to deal
    with this issue in the real world (receiving data over an RS232
    line, subject to ocassional 'noise'). My program was not able
    to make *any* assumptions about the expected data stream.

    'Knowing what I was doing', I knew that such 'guarantee' was
    impossible to implement. 'Knowing what I was doing' meant that
    it was my program's responsibility to deal with 'dirty' data
    in a safe manner (e.g. discarding it, or perhaps re-acquiring it).


    -Mike
     
    Mike Wahler, Nov 3, 2005
    #18
  19. Rolf Magnus wrote:
    > It's always potentially being ill-formed.


    That's like saying that every value that you set is potentially
    invalid. If I have a set output from another digital source on the
    machine, it COULD be ill-formed if the machine doesn't work as it's
    suppose to, just as if a pointer set to a certain object could randomly
    change from the OS not operating as it is suppose to and overwriting
    that segment of memory.
     
    Josh Mcfarlane, Nov 4, 2005
    #19
  20. Marcus

    Rolf Magnus Guest

    Pete Becker wrote:

    > Rolf Magnus wrote:
    >>
    >> Ok, let's apply technical terms then:
    >> According to the C++ standard, UB is "behavior, such as might arise upon
    >> use of an erronous program construct or erroneous data, for which this
    >> International Standard imposes no requirements". Applying that to your
    >> sentence above, that means that my program has "an erronous program
    >> construct or erroneous data", if the input is too large and is correct if
    >> the input fits in the provided space. But my program can't control
    >> whenther the input fits or not. It can control the size of the buffer,
    >> but not the amount of data coming in, so it doesn't have any way of
    >> ensuring the well-defined behavior that you are writing about.

    >
    > That's correct.


    So, you think the correctness of a C++ program can depend on what the user
    enters at run-time?

    >> It's as if you say "the behavior is well-defined only on full moon".
    >>

    >
    > No, it's not. Not being able to control input is not the same as input
    > always being ill-formed.


    It's always potentially being ill-formed.

    > For a quick and dirty one-off command line utility I'd have no qualms
    > about using gets.


    That way of thinking is the reason for quite a lot of security holes.
     
    Rolf Magnus, Nov 4, 2005
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Barney Barumba
    Replies:
    0
    Views:
    580
    Barney Barumba
    Jul 23, 2003
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,260
    Smokey Grindel
    Dec 2, 2006
  3. BoBi
    Replies:
    3
    Views:
    4,282
  4. Randy Lawrence
    Replies:
    10
    Views:
    192
    Robert Klemme
    Jul 5, 2004
  5. Pete Elmore

    'gets' has been hijacked

    Pete Elmore, Jun 6, 2005, in forum: Ruby
    Replies:
    3
    Views:
    147
    Pete Elmore
    Jun 6, 2005
Loading...

Share This Page