about design consideration of strcpy()

Discussion in 'C Programming' started by steve yee, May 25, 2006.

  1. steve yee

    steve yee Guest

    steve yee, May 25, 2006
    #1
    1. Advertising

  2. steve yee

    steve yee Guest

    > most people seem to not think it as a problemic design.

    sorry. it should be:
    most people seem to think it as a problemic design.
     
    steve yee, May 25, 2006
    #2
    1. Advertising

  3. On 2006-05-25, steve yee <> wrote:
    >> most people seem to not think it as a problemic design.

    >
    > sorry. it should be:
    > most people seem to think it as a problemic design.
    >


    I can't imagine what the C++ folks know about C. There is absolutely
    nothing wrong with strcpy's design.

    --
    Andrew Poelstra < http://www.wpsoftware.net/blog >
    To email me, use "apoelstra" at the above address.
    It's just like stealing teeth from a baby.
     
    Andrew Poelstra, May 25, 2006
    #3
  4. steve yee

    jacob navia Guest

    Andrew Poelstra a écrit :
    > On 2006-05-25, steve yee <> wrote:
    >
    >>>most people seem to not think it as a problemic design.

    >>
    >>sorry. it should be:
    >> most people seem to think it as a problemic design.
    >>

    >
    >
    > I can't imagine what the C++ folks know about C. There is absolutely
    > nothing wrong with strcpy's design.
    >


    Everything is wrong in that design:

    1) No provision for bounds of the character strings. strcpy is the most
    often found culprit of buffer overflows and memory overwrites.
    2) The return value makes no provision for error reporting. This is
    in most cases a bad design.
    3) The return value returns no useful information.
     
    jacob navia, May 25, 2006
    #4
  5. Andrew Poelstra <> writes:
    > On 2006-05-25, steve yee <> wrote:
    >>> most people seem to not think it as a problemic design.

    >>
    >> sorry. it should be:
    >> most people seem to think it as a problemic design.
    >>

    >
    > I can't imagine what the C++ folks know about C. There is absolutely
    > nothing wrong with strcpy's design.


    Presumably they know about the parts of C that are included by
    reference in the C++ standard. That includes strcpy().

    I think the point of having strcpy() return its first argument is to
    allow calls to be chained together. For example:

    strcat(strcpy(s1, s2), s3);

    Personally, I'm not convinced this is all that useful; I find it
    clearer to do one call at a time:

    strcpy(s1, s2);
    strcat(s1, s3);

    which can also make it easier to confirm there's enough room for the
    result.

    I think the real answer is historical precedent.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, May 25, 2006
    #5
  6. Andrew Poelstra said:

    > On 2006-05-25, steve yee <> wrote:
    >>> most people seem to not think it as a problemic design.

    >>
    >> sorry. it should be:
    >> most people seem to think it as a problemic design.
    >>

    >
    > I can't imagine what the C++ folks know about C.


    Some of them are pretty bright, you know - and some are even C experts who
    happen not to like the language as much as they like C++. (Weird, I know,
    but then there's nowt as queer as folk.)

    > There is absolutely nothing wrong with strcpy's design.


    Yeah there is. It ought to return a pointer to the null terminator. Giving
    back the pointer you gave it in the first place is a complete waste of
    time.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 25, 2006
    #6
  7. steve yee

    Tomás Guest

    Richard Heathfield posted:


    > Some of them are pretty bright, you know - and some are even C experts
    > who happen not to like the language as much as they like C++. (Weird,
    > I know, but then there's nowt as queer as folk.)


    I know my way inside out through the C subset of C++. I can do everything
    I want to do in C, but I haven't got its Standard memorised as much as
    the C++ Standard. For instance, yesterday I was hesitant to state the
    following:


    int array[5] = { 3, 4 };

    /* First two elements are 3, 4, and all others are zero */


    I know without a shadow of a doubt that this is true for C++, but didn't
    want to post misinformation just in case I was wrong about C.

    Even though I'm an expert C++ programmer, and know its every fancy
    feature inside out, I'm still an expert at the lower-level stuff which
    are held in common with C.

    (Before I say anything: I'm not waving the C++ flag on a C newsgroup, but
    since the topic's been brought up:) I myself prefer C++. That said, a
    lot of my C++ code will compile as C code (i.e. I like to keep things
    basic), but there are times when the more fancy features are definitely
    preferable. Even when I'm writing C code, I can find plenty of places
    where I'd like to use a template, but can't.

    The reason I read and post on this C newsgroup is that there's a lot more
    posts about the "lower-level" stuff, than you would find on a C++
    newsgroup. In general, I prefer the lower-level stuff to the higher-level
    stuff.

    -Tomás
     
    Tomás, May 25, 2006
    #7
  8. On 2006-05-25, Richard Heathfield <> wrote:
    > Andrew Poelstra said:
    >
    >> On 2006-05-25, steve yee <> wrote:
    >>>> most people seem to not think it as a problemic design.
    >>>
    >>> sorry. it should be:
    >>> most people seem to think it as a problemic design.
    >>>

    >>
    >> I can't imagine what the C++ folks know about C.

    >
    > Some of them are pretty bright, you know - and some are even C experts who
    > happen not to like the language as much as they like C++. (Weird, I know,
    > but then there's nowt as queer as folk.)
    >

    Absolutely true. That's not what I meant. strcpy doesn't fit in with C++'s
    idea of everything being simple and beautiful and not having pointers.
    Therefore, even if a person is a C expert, if they prefer C++, their opinion
    will be skewed in a C++ey way.

    --
    Andrew Poelstra < http://www.wpsoftware.net/blog >
    To email me, use "apoelstra" at the above address.
    It's just like stealing teeth from a baby.
     
    Andrew Poelstra, May 25, 2006
    #8
  9. steve yee

    CBFalconer Guest

    Richard Heathfield wrote:
    > Andrew Poelstra said:
    >> On 2006-05-25, steve yee <> wrote:
    >>
    >>>> most people seem to not think it as a problemic design.
    >>>
    >>> sorry. it should be:
    >>> most people seem to think it as a problemic design.

    >>
    >> I can't imagine what the C++ folks know about C.

    >
    > Some of them are pretty bright, you know - and some are even C
    > experts who happen not to like the language as much as they like
    > C++. (Weird, I know, but then there's nowt as queer as folk.)
    >
    >> There is absolutely nothing wrong with strcpy's design.

    >
    > Yeah there is. It ought to return a pointer to the null
    > terminator. Giving back the pointer you gave it in the first
    > place is a complete waste of time.


    Except that is the wrong problem. Such routines are better off
    returning void, to prevent the sort of chaining that often gets
    done. Consider a hypothetical strrev(s) routine, that returns the
    value of s, and reverses the string in place. It can then be used
    as:

    printf("%s\n%s\n", s, strrev(s));

    which looks clean. However the results will surprise the user,
    because both printed strings are the reverse form. If the routine
    returns void then the user would have written:

    puts(s); strrev(s); puts(s);

    and the birds would sing, the sun would shine...

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, May 25, 2006
    #9
  10. steve yee

    Default User Guest

    Richard Heathfield wrote:

    > Andrew Poelstra said:


    > > I can't imagine what the C++ folks know about C.

    >
    > Some of them are pretty bright, you know - and some are even C
    > experts who happen not to like the language as much as they like C++.
    > (Weird, I know, but then there's nowt as queer as folk.)


    And some are old C programmers who happen to work in jobs that require
    C++.




    Brian
     
    Default User, May 25, 2006
    #10
  11. CBFalconer wrote:
    >
    > Richard Heathfield wrote:
    > > Andrew Poelstra said:
    > >> On 2006-05-25, steve yee <> wrote:
    > >>
    > >>>> most people seem to not think it as a problemic design.
    > >>>
    > >>> sorry. it should be:
    > >>> most people seem to think it as a problemic design.
    > >>
    > >> I can't imagine what the C++ folks know about C.

    > >
    > > Some of them are pretty bright, you know - and some are even C
    > > experts who happen not to like the language as much as they like
    > > C++. (Weird, I know, but then there's nowt as queer as folk.)
    > >
    > >> There is absolutely nothing wrong with strcpy's design.

    > >
    > > Yeah there is. It ought to return a pointer to the null
    > > terminator. Giving back the pointer you gave it in the first
    > > place is a complete waste of time.

    >
    > Except that is the wrong problem. Such routines are better off
    > returning void, to prevent the sort of chaining that often gets
    > done. Consider a hypothetical strrev(s) routine, that returns the
    > value of s, and reverses the string in place. It can then be used
    > as:
    >
    > printf("%s\n%s\n", s, strrev(s));
    >
    > which looks clean. However the results will surprise the user,
    > because both printed strings are the reverse form. If the routine
    > returns void then the user would have written:
    >
    > puts(s); strrev(s); puts(s);
    >
    > and the birds would sing, the sun would shine...
    >

    ....or with the "strrev()" that returns the pointer, you could write:

    printf("%s\n%s\n",strrev(s),strrev(s));

    Now *no* matter which way things are evaluated, the strings will
    be the reverse of each other... ;-)


    --
    +----------------------------------------------------------------+
    | Charles and Francis Richmond richmond at plano dot net |
    +----------------------------------------------------------------+
     
    Charles Richmond, May 25, 2006
    #11
  12. steve yee

    CBFalconer Guest

    Charles Richmond wrote:
    > CBFalconer wrote:
    >>

    .... snip ...
    >>
    >> Except that is the wrong problem. Such routines are better off
    >> returning void, to prevent the sort of chaining that often gets
    >> done. Consider a hypothetical strrev(s) routine, that returns the
    >> value of s, and reverses the string in place. It can then be used
    >> as:
    >>
    >> printf("%s\n%s\n", s, strrev(s));
    >>
    >> which looks clean. However the results will surprise the user,
    >> because both printed strings are the reverse form. If the routine
    >> returns void then the user would have written:
    >>
    >> puts(s); strrev(s); puts(s);
    >>
    >> and the birds would sing, the sun would shine...
    >>

    > ...or with the "strrev()" that returns the pointer, you could write:
    >
    > printf("%s\n%s\n",strrev(s),strrev(s));
    >
    > Now *no* matter which way things are evaluated, the strings will
    > be the reverse of each other... ;-)


    Surprise. No they won't be reverses of each other. Try it and
    see. That is the evil caused by returning the parameter pointer as
    a result. Think about it.

    Here's a strrev routine for you to test with: The comments
    indicate how to make it return the input pointer.

    /* ======================= */
    /* reverse string in place */
    void revstring(char *string)
    {
    char *last, temp;
    /* char *s = string; */

    last = string + strlen(string); /* points to '\0' */
    if (*string)
    while (last-- > string) {
    temp = *string; *string++ = *last; *last = temp;
    }
    /* return s */
    } /* revstring */

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, May 25, 2006
    #12
  13. steve yee

    pete Guest

    CBFalconer wrote:
    >
    > Charles Richmond wrote:
    > > CBFalconer wrote:
    > >>

    > ... snip ...
    > >>
    > >> Except that is the wrong problem. Such routines are better off
    > >> returning void, to prevent the sort of chaining that often gets
    > >> done. Consider a hypothetical strrev(s) routine, that returns the
    > >> value of s, and reverses the string in place. It can then be used
    > >> as:
    > >>
    > >> printf("%s\n%s\n", s, strrev(s));
    > >>
    > >> which looks clean. However the results will surprise the user,
    > >> because both printed strings are the reverse form. If the routine
    > >> returns void then the user would have written:
    > >>
    > >> puts(s); strrev(s); puts(s);
    > >>
    > >> and the birds would sing, the sun would shine...
    > >>

    > > ...or with the "strrev()" that returns the pointer, you could write:
    > >
    > > printf("%s\n%s\n",strrev(s),strrev(s));
    > >
    > > Now *no* matter which way things are evaluated, the strings will
    > > be the reverse of each other... ;-)

    >
    > Surprise. No they won't be reverses of each other.


    That's a good one.
    The side effects of both strrev calls are complete,
    before printf's side effects begin.

    --
    pete
     
    pete, May 26, 2006
    #13
  14. CBFalconer wrote:
    >
    > Charles Richmond wrote:
    > > CBFalconer wrote:
    > >>

    > ... snip ...
    > >>
    > >> Except that is the wrong problem. Such routines are better off
    > >> returning void, to prevent the sort of chaining that often gets
    > >> done. Consider a hypothetical strrev(s) routine, that returns the
    > >> value of s, and reverses the string in place. It can then be used
    > >> as:
    > >>
    > >> printf("%s\n%s\n", s, strrev(s));
    > >>
    > >> which looks clean. However the results will surprise the user,
    > >> because both printed strings are the reverse form. If the routine
    > >> returns void then the user would have written:
    > >>
    > >> puts(s); strrev(s); puts(s);
    > >>
    > >> and the birds would sing, the sun would shine...
    > >>

    > > ...or with the "strrev()" that returns the pointer, you could write:
    > >
    > > printf("%s\n%s\n",strrev(s),strrev(s));
    > >
    > > Now *no* matter which way things are evaluated, the strings will
    > > be the reverse of each other... ;-)

    >

    You are right. I am caught again in a familiar trap. The "printf()"
    just passes the pointer to the string twice, and the string remains as
    it was the *last* time that "strrev()" was run.

    At a PPoE, I fixed a c program that someone else had written. There
    was a function to do something to a copy of a string. The function
    copied the string into a static local string variable, did the
    conversion there, and returned the pointer to the static local string.

    The problem resulted from calling this function *twice* in the same
    parameter list. It is strikingly similar to what happened with
    "strrev()" above. Programmer beware!!!


    --
    +----------------------------------------------------------------+
    | Charles and Francis Richmond richmond at plano dot net |
    +----------------------------------------------------------------+
     
    Charles Richmond, May 26, 2006
    #14
    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. Ryan Ternier
    Replies:
    0
    Views:
    340
    Ryan Ternier
    Jan 10, 2006
  2. David MacQuigg

    Is classless worth consideration

    David MacQuigg, Apr 29, 2004, in forum: Python
    Replies:
    33
    Views:
    872
    Erik Max Francis
    May 3, 2004
  3. RGK
    Replies:
    4
    Views:
    327
  4. Starman

    Consideration on pointer declarations

    Starman, Mar 5, 2009, in forum: C Programming
    Replies:
    18
    Views:
    596
    JosephKK
    Mar 13, 2009
  5. Henke

    Design consideration regarding dynamic controls

    Henke, May 7, 2004, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    124
    Henke
    May 7, 2004
Loading...

Share This Page