why do strcpy, strcat, & co return a pointer ?

Discussion in 'C Programming' started by Jarmo, Nov 22, 2003.

  1. Jarmo

    Jarmo Guest

    "Nicolas" <> wrote in message
    news:3fbfeb99$0$27046$...
    > On most implementations of the standard C library, the functions that
    > copy characters in a previously allocated buffer, like strcpy or strcat,
    > are returning the pointer to that buffer.
    >
    > On my NetBSD system, man strcpy gives the following prototype :
    > char *strcpy(char * restrict dst, const char * restrict src);
    >
    > What's the point in returning a pointer we already know before the call?
    >
    > Thank you in advance for an explanation.


    So that you can write (unnecessarily abbreviated) code like this:

    strcat(path, strcpy(file, "fred.txt"));
     
    Jarmo, Nov 22, 2003
    #1
    1. Advertising

  2. Jarmo

    Nicolas Guest

    On most implementations of the standard C library, the functions that
    copy characters in a previously allocated buffer, like strcpy or strcat,
    are returning the pointer to that buffer.

    On my NetBSD system, man strcpy gives the following prototype :
    char *strcpy(char * restrict dst, const char * restrict src);

    What's the point in returning a pointer we already know before the call?

    Thank you in advance for an explanation.
     
    Nicolas, Nov 23, 2003
    #2
    1. Advertising

  3. Jarmo

    Mike Wahler Guest

    "Nicolas" <> wrote in message
    news:3fbfeb99$0$27046$...
    > On most implementations of the standard C library, the functions that
    > copy characters in a previously allocated buffer, like strcpy or strcat,
    > are returning the pointer to that buffer.
    >
    > On my NetBSD system, man strcpy gives the following prototype :
    > char *strcpy(char * restrict dst, const char * restrict src);
    >
    > What's the point in returning a pointer we already know before the call?


    Convenience. The result of one of these function calls might
    be used as part of a larger expression, e.g.:

    printf("%s\n", strcat(s1, s2));

    If you don't need the return value, just ignore it.

    strcat(s1, s2);

    -Mike
     
    Mike Wahler, Nov 23, 2003
    #3
  4. Jarmo

    CBFalconer Guest

    Nicolas wrote:
    >
    > On most implementations of the standard C library, the functions
    > that copy characters in a previously allocated buffer, like strcpy
    > or strcat, are returning the pointer to that buffer.
    >
    > On my NetBSD system, man strcpy gives the following prototype :
    > char *strcpy(char * restrict dst, const char * restrict src);
    >
    > What's the point in returning a pointer we already know before the
    > call?


    It allows you to be baffled by the peculiar run-time actions of:

    char p[100] = "Fred";
    ....
    printf("%s or %s\n", p, strcat(p, " and George"));

    For improved semantics look up the (non-standard) strlcat and
    strlcpy functions.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Nov 23, 2003
    #4
  5. Nicolas wrote:
    > On most implementations of the standard C library, the functions that
    > copy characters in a previously allocated buffer, like strcpy or strcat,
    > are returning the pointer to that buffer.


    On ALL implementations. If an implementation were to do something
    different, it would no longer be an implementation of the *standard* C
    library.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Nov 23, 2003
    #5
  6. Jarmo

    Ben Pfaff Guest

    CBFalconer <> writes:

    > It allows you to be baffled by the peculiar run-time actions of:
    >
    > char p[100] = "Fred";
    > ....
    > printf("%s or %s\n", p, strcat(p, " and George"));


    That code has undefined behavior, you know.
    --
    "The expression isn't unclear *at all* and only an expert could actually
    have doubts about it"
    --Dan Pop
     
    Ben Pfaff, Nov 23, 2003
    #6
  7. Nicolas wrote:

    > Jarmo wrote:
    >> "Nicolas" <> wrote in message
    >> news:3fbfeb99$0$27046$...
    >>
    >>>On most implementations of the standard C library, the functions that
    >>>copy characters in a previously allocated buffer, like strcpy or strcat,
    >>>are returning the pointer to that buffer.
    >>>
    >>>On my NetBSD system, man strcpy gives the following prototype :
    >>>char *strcpy(char * restrict dst, const char * restrict src);
    >>>
    >>>What's the point in returning a pointer we already know before the call?
    >>>
    >>>Thank you in advance for an explanation.

    >>
    >>
    >> So that you can write (unnecessarily abbreviated) code like this:
    >>
    >> strcat(path, strcpy(file, "fred.txt"));

    >
    > Lol, of course this is obvious.
    > That's because I never (well almost) enclose a call in another call.


    It's probably wise to never (well almost) enclose a call in another call.
    Many functions return error indicators which can be missed by such an
    approach.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Nov 23, 2003
    #7
  8. Jarmo

    Nicolas Guest

    Jarmo wrote:
    > "Nicolas" <> wrote in message
    > news:3fbfeb99$0$27046$...
    >
    >>On most implementations of the standard C library, the functions that
    >>copy characters in a previously allocated buffer, like strcpy or strcat,
    >>are returning the pointer to that buffer.
    >>
    >>On my NetBSD system, man strcpy gives the following prototype :
    >>char *strcpy(char * restrict dst, const char * restrict src);
    >>
    >>What's the point in returning a pointer we already know before the call?
    >>
    >>Thank you in advance for an explanation.

    >
    >
    > So that you can write (unnecessarily abbreviated) code like this:
    >
    > strcat(path, strcpy(file, "fred.txt"));
    >
    >


    Lol, of course this is obvious.
    That's because I never (well almost) enclose a call in another call.
    Thx.
     
    Nicolas, Nov 23, 2003
    #8
  9. Jarmo

    Simon Biber Guest

    "Ben Pfaff" <> wrote:
    > CBFalconer <> writes:
    > > It allows you to be baffled by the peculiar run-time actions of:
    > >
    > > char p[100] = "Fred";
    > > ....
    > > printf("%s or %s\n", p, strcat(p, " and George"));

    >
    > That code has undefined behavior, you know.


    It does? Sorry, I don't get it.

    Assuming you make it into a complete program:

    #include <stdio.h>
    #include <string.h>

    int main(void)
    {
    char p[100] = "Fred";
    printf("%s or %s\n", p, strcat(p, " and George"));
    return 0;
    }

    --
    Simon.
     
    Simon Biber, Nov 23, 2003
    #9
  10. Jarmo

    Joe Wright Guest

    Richard Heathfield wrote:
    >
    > Nicolas wrote:
    >
    > >>
    > >> strcat(path, strcpy(file, "fred.txt"));

    > >
    > > Lol, of course this is obvious.
    > > That's because I never (well almost) enclose a call in another call.

    >
    > It's probably wise to never (well almost) enclose a call in another call.
    > Many functions return error indicators which can be missed by such an
    > approach.
    >

    But surely many (most?) are expressions with value. I would use the
    trick above without batting an eye. I some string manipulation stuff I
    wrote..

    char *ltrim(char *s); /* remove leading whitespace, return s */
    char *rtrim(char *s); /* remove trailing whitespace, return s */

    char *alltrim(char *s) {
    return ltrim(rtrim(s));
    }
    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Nov 23, 2003
    #10
  11. In article <3fc0c377$0$14048$>,
    Simon Biber <> wrote:
    >"Ben Pfaff" <> wrote:
    >> CBFalconer <> writes:
    >> > It allows you to be baffled by the peculiar run-time actions of:
    >> >
    >> > char p[100] = "Fred";
    >> > ....
    >> > printf("%s or %s\n", p, strcat(p, " and George"));

    >>
    >> That code has undefined behavior, you know.

    >
    >It does? Sorry, I don't get it.
    >
    >Assuming you make it into a complete program:
    >
    >#include <stdio.h>
    >#include <string.h>
    >
    >int main(void)
    >{
    > char p[100] = "Fred";
    > printf("%s or %s\n", p, strcat(p, " and George"));
    > return 0;
    >}


    What do you expect the first %s to print?


    --
    Rouben Rostamian
     
    Rouben Rostamian, Nov 23, 2003
    #11
  12. Jarmo

    cody Guest

    > >> > It allows you to be baffled by the peculiar run-time actions of:
    > >> >
    > >> > char p[100] = "Fred";
    > >> > ....
    > >> > printf("%s or %s\n", p, strcat(p, " and George"));
    > >>
    > >> That code has undefined behavior, you know.

    > >
    > >It does? Sorry, I don't get it.
    > >
    > >Assuming you make it into a complete program:
    > >
    > >#include <stdio.h>
    > >#include <string.h>
    > >
    > >int main(void)
    > >{
    > > char p[100] = "Fred";
    > > printf("%s or %s\n", p, strcat(p, " and George"));
    > > return 0;
    > >}

    >
    > What do you expect the first %s to print?


    The order in which arguments are evaluated is undefined.

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Nov 23, 2003
    #12
  13. In article <bpqk09$jbg$>,
    (Rouben Rostamian) wrote:

    > In article <3fc0c377$0$14048$>,
    > Simon Biber <> wrote:
    > >"Ben Pfaff" <> wrote:
    > >> CBFalconer <> writes:
    > >> > It allows you to be baffled by the peculiar run-time actions of:
    > >> >
    > >> > char p[100] = "Fred";
    > >> > ....
    > >> > printf("%s or %s\n", p, strcat(p, " and George"));
    > >>
    > >> That code has undefined behavior, you know.

    > >
    > >It does? Sorry, I don't get it.
    > >
    > >Assuming you make it into a complete program:
    > >
    > >#include <stdio.h>
    > >#include <string.h>
    > >
    > >int main(void)
    > >{
    > > char p[100] = "Fred";
    > > printf("%s or %s\n", p, strcat(p, " and George"));
    > > return 0;
    > >}

    >
    > What do you expect the first %s to print?


    This is a good one.

    The obvious (and wrong) answer is "Fred".
    The not so obvious and correct answer is "Fred and George".
    After that you might feel doubt whether this invokes undefined behavior;
    it sure is weird enough.
    But it doesn't, it is perfectly fine C.
     
    Christian Bau, Nov 23, 2003
    #13
  14. In article <bpqmuq$1qcsig$-berlin.de>,
    "cody" <> wrote:

    > > >> > It allows you to be baffled by the peculiar run-time actions of:
    > > >> >
    > > >> > char p[100] = "Fred";
    > > >> > ....
    > > >> > printf("%s or %s\n", p, strcat(p, " and George"));
    > > >>
    > > >> That code has undefined behavior, you know.
    > > >
    > > >It does? Sorry, I don't get it.
    > > >
    > > >Assuming you make it into a complete program:
    > > >
    > > >#include <stdio.h>
    > > >#include <string.h>
    > > >
    > > >int main(void)
    > > >{
    > > > char p[100] = "Fred";
    > > > printf("%s or %s\n", p, strcat(p, " and George"));
    > > > return 0;
    > > >}

    > >
    > > What do you expect the first %s to print?

    >
    > The order in which arguments are evaluated is undefined.


    Correct (except that it is "unspecified"), and completely irrelevant.
     
    Christian Bau, Nov 23, 2003
    #14
  15. Joe Wright wrote:

    > Richard Heathfield wrote:
    >>
    >> Nicolas wrote:
    >> > That's because I never (well almost) enclose a call in another call.

    >> It's probably wise to never (well almost) enclose a call in another call.
    >> Many functions return error indicators which can be missed by such an
    >> approach.
    >>

    > But surely many (most?) are expressions with value. I would use the
    > trick above without batting an eye. I some string manipulation stuff I
    > wrote..
    >
    > char *ltrim(char *s); /* remove leading whitespace, return s */
    > char *rtrim(char *s); /* remove trailing whitespace, return s */
    >
    > char *alltrim(char *s) {
    > return ltrim(rtrim(s));
    > }


    Fair enough in that example, but consider, for example, the very dubious
    example of strcpy(p = malloc(strlen(s) + 1), s);

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Nov 23, 2003
    #15
  16. "Ben Pfaff" <> wrote in message
    news:...
    > CBFalconer <> writes:
    >
    > > It allows you to be baffled by the peculiar run-time actions of:
    > >
    > > char p[100] = "Fred";
    > > ....
    > > printf("%s or %s\n", p, strcat(p, " and George"));

    >
    > That code has undefined behavior, you know.


    Are you saying printf could be a function macro, hence no sequence point
    until after the first "%s" output, during which strcat might still be
    modifying p?

    Soln: (printf)("%s or %s\n", p, strcat(p, " and George"));

    Or are you saying that strcat could be a macro and the second argument p
    counts as a 'read' of the p elements' prior value?

    Or is it something else?

    Please elaborate.

    --
    Peter
     
    Peter Nilsson, Nov 23, 2003
    #16
  17. Rouben Rostamian wrote:

    > In article <3fc0c377$0$14048$>,
    > Simon Biber <> wrote:
    >
    >>"Ben Pfaff" <> wrote:
    >>>
    >>>That code has undefined behavior, you know.

    >>
    >>It does? Sorry, I don't get it.
    >>
    >>Assuming you make it into a complete program:
    >>
    >>#include <stdio.h>
    >>#include <string.h>
    >>
    >>int main(void)
    >>{
    >> char p[100] = "Fred";
    >> printf("%s or %s\n", p, strcat(p, " and George"));
    >> return 0;
    >>}

    >
    >
    > What do you expect the first %s to print?
    >


    That is not relevant to the question. If the behavior is undefined, it
    need not print anything that one could predict, or anything at all.

    I believe the behavior is well-defined, and the output will be:

    Fred and George or Fred and George

    But I'm afraid that I'm in dangerous territory disagreeing with Ben. If
    it is, in fact, undefined then I would certainly like to know why.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Nov 23, 2003
    #17
  18. Jarmo

    cody Guest

    > > > >> > It allows you to be baffled by the peculiar run-time actions of:
    > > > >> >
    > > > >> > char p[100] = "Fred";
    > > > >> > ....
    > > > >> > printf("%s or %s\n", p, strcat(p, " and George"));
    > > > >>
    > > > >> That code has undefined behavior, you know.
    > > > >
    > > > >It does? Sorry, I don't get it.
    > > > >
    > > > >Assuming you make it into a complete program:
    > > > >
    > > > >#include <stdio.h>
    > > > >#include <string.h>
    > > > >
    > > > >int main(void)
    > > > >{
    > > > > char p[100] = "Fred";
    > > > > printf("%s or %s\n", p, strcat(p, " and George"));
    > > > > return 0;
    > > > >}
    > > >
    > > > What do you expect the first %s to print?

    > >
    > > The order in which arguments are evaluated is undefined.

    >
    > Correct (except that it is "unspecified"), and completely irrelevant.


    What is the difference between undefined and unspecified? When I don't
    specify or define something it is undefined/unspecified.
    Note: I don't said "undefined behaviour" which is something completely
    different.

    And why is it irrelevant here? The output in the example depends on the
    order of parameter evaluation.

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Nov 23, 2003
    #18
  19. Jarmo

    cody Guest

    > > > >> > It allows you to be baffled by the peculiar run-time actions of:
    > > > >> >
    > > > >> > char p[100] = "Fred";
    > > > >> > ....
    > > > >> > printf("%s or %s\n", p, strcat(p, " and George"));
    > > > >>
    > > > >> That code has undefined behavior, you know.
    > > > >
    > > > >It does? Sorry, I don't get it.
    > > > >
    > > > >Assuming you make it into a complete program:
    > > > >
    > > > >#include <stdio.h>
    > > > >#include <string.h>
    > > > >
    > > > >int main(void)
    > > > >{
    > > > > char p[100] = "Fred";
    > > > > printf("%s or %s\n", p, strcat(p, " and George"));
    > > > > return 0;
    > > > >}
    > > >
    > > > What do you expect the first %s to print?

    > >
    > > The order in which arguments are evaluated is undefined.

    >
    > Correct (except that it is "unspecified"), and completely irrelevant.


    Oh sorry I just noticed that the order of parameter evaluation in fact does
    not affect the output in this example.
    The output will always be: "Fred and George or Fred and George".

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Nov 23, 2003
    #19
  20. cody wrote:

    >>>
    >>>The order in which arguments are evaluated is undefined.

    >>
    >>Correct (except that it is "unspecified"), and completely irrelevant.

    >
    >
    > What is the difference between undefined and unspecified? When I don't
    > specify or define something it is undefined/unspecified.
    > Note: I don't said "undefined behaviour" which is something completely
    > different.


    Unspecified: Multiple options are presented, one *must* be used.
    Undefined: No constraints at all.

    >
    > And why is it irrelevant here? The output in the example depends on the
    > order of parameter evaluation.


    Because the claim was that the behavior is undefined. It's not clear how
    different orders of evaluation for the parameters would lead to
    undefined behavior.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Nov 23, 2003
    #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. JC

    strcpy and strcat problem

    JC, Sep 26, 2003, in forum: C Programming
    Replies:
    23
    Views:
    1,939
    Robert B. Clark
    Sep 29, 2003
  2. Pascal Damian

    Difference between strcpy() and strcat()?

    Pascal Damian, Mar 5, 2004, in forum: C Programming
    Replies:
    9
    Views:
    13,857
    Pascal Damian
    Mar 6, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,225
    Smokey Grindel
    Dec 2, 2006
  4. lynology

    Bad File Descriptor Error on strcat/strcpy

    lynology, Aug 18, 2004, in forum: C Programming
    Replies:
    4
    Views:
    541
    Chris Torek
    Aug 18, 2004
  5. strcpy and strcat's return type

    , Jul 26, 2005, in forum: C Programming
    Replies:
    14
    Views:
    819
    Kenneth Brody
    Aug 22, 2005
Loading...

Share This Page