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

J

Jarmo

Nicolas said:
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"));
 
N

Nicolas

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.
 
M

Mike Wahler

Nicolas said:
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
 
C

CBFalconer

Nicolas said:
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.
 
K

Kevin Goodsell

Nicolas said:
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
 
B

Ben Pfaff

CBFalconer said:
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.
 
R

Richard Heathfield

Nicolas said:
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.
 
N

Nicolas

Jarmo said:
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.
 
S

Simon Biber

Ben Pfaff said:
CBFalconer said:
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;
}
 
J

Joe Wright

Richard said:
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));
}
 
R

Rouben Rostamian

Ben Pfaff said:
CBFalconer said:
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?
 
C

cody

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.
 
C

Christian Bau

Ben Pfaff said:
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.
 
C

Christian Bau

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.[/QUOTE]

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

Richard Heathfield

Joe said:
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);
 
P

Peter Nilsson

Ben Pfaff said:
CBFalconer said:
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.
 
K

Kevin Goodsell

Rouben said:
Simon Biber said:
Ben Pfaff said:
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
 
C

cody

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.
 
C

cody

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".
 
K

Kevin Goodsell

cody said:
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
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top