By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,614 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

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

P: n/a
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.

Nov 13 '05 #1
Share this Question
Share on Google+
44 Replies


P: n/a
"Nicolas" <ad*@serpe.org> wrote in message
news:3f***********************@news.free.fr...
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"));
Nov 13 '05 #2

P: n/a

"Nicolas" <ad*@serpe.org> wrote in message
news:3f***********************@news.free.fr...
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
Nov 13 '05 #3

P: n/a
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 (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #4

P: n/a
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.

Nov 13 '05 #5

P: n/a
CBFalconer <cb********@yahoo.com> 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
Nov 13 '05 #6

P: n/a
Jarmo wrote:
"Nicolas" <ad*@serpe.org> wrote in message
news:3f***********************@news.free.fr...
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.

Nov 13 '05 #7

P: n/a
Nicolas wrote:
Jarmo wrote:
"Nicolas" <ad*@serpe.org> wrote in message
news:3f***********************@news.free.fr...
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 : bi****@eton.powernet.co.uk
"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
Nov 13 '05 #8

P: n/a
"Ben Pfaff" <bl*@cs.stanford.edu> wrote:
CBFalconer <cb********@yahoo.com> 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.
Nov 13 '05 #9

P: n/a
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 ---
Nov 13 '05 #10

P: n/a
In article <3f***********************@news.optusnet.com.au> ,
Simon Biber <ne**@ralminNOSPAM.cc> wrote:
"Ben Pfaff" <bl*@cs.stanford.edu> wrote:
CBFalconer <cb********@yahoo.com> 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
Nov 13 '05 #11

P: n/a
> >> > 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
Nov 13 '05 #12

P: n/a
In article <bp**********@pc18.math.umbc.edu>,
ro****@pc18.math.umbc.edu (Rouben Rostamian) wrote:
In article <3f***********************@news.optusnet.com.au> ,
Simon Biber <ne**@ralminNOSPAM.cc> wrote:
"Ben Pfaff" <bl*@cs.stanford.edu> wrote:
CBFalconer <cb********@yahoo.com> 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.
Nov 13 '05 #13

P: n/a
In article <bp*************@ID-176797.news.uni-berlin.de>,
"cody" <do*********************@gmx.de> 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.
Nov 13 '05 #14

P: n/a
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 : bi****@eton.powernet.co.uk
"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
Nov 13 '05 #15

P: n/a
"Ben Pfaff" <bl*@cs.stanford.edu> wrote in message
news:87************@pfaff.stanford.edu...
CBFalconer <cb********@yahoo.com> 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
Nov 13 '05 #16

P: n/a
Rouben Rostamian wrote:
In article <3f***********************@news.optusnet.com.au> ,
Simon Biber <ne**@ralminNOSPAM.cc> wrote:
"Ben Pfaff" <bl*@cs.stanford.edu> 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.

Nov 13 '05 #17

P: n/a
> > > >> > 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
Nov 13 '05 #18

P: n/a
> > > >> > 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
Nov 13 '05 #19

P: n/a
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.

Nov 13 '05 #20

P: n/a
> >>>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.


Thanks, I will remember it next time.
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.


I didn't claim that something would lead to undefined behaviour, I just said
that the order of parameter evaluation is undefined.
But you was right, in that example the order of parameter evaluation does
not make any difference (it would, when p would be an int instead of char*)

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 13 '05 #21

P: n/a
In article <bp*************@ID-176797.news.uni-berlin.de>,
"cody" <do*********************@gmx.de> 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.


What is the difference between undefined and unspecified? When I don't
specify or define something it is undefined/unspecified.


Both "undefined" and "unspecified" have very defined meanings in the C
Standard, and their meaning is different.
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.


No, it doesn't.
Nov 13 '05 #22

P: n/a
"Rouben Rostamian" <ro****@pc18.math.umbc.edu> wrote:
Simon Biber <ne**@ralminNOSPAM.cc> wrote:
#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?


I expect the first %s to print "Fred and George". By the time the
printf function is called, all side effects from the modification
of the array must be completed. I see no undefined behaviour,
it must print "Fred and George or Fred and George\n".

I see no problem evaluating p twice; its value does not change!

--
Simon.
Nov 13 '05 #23

P: n/a
In article <3f***********************@news.optusnet.com.au> ,
Simon Biber <ne**@ralminNOSPAM.cc> wrote:
"Rouben Rostamian" <ro****@pc18.math.umbc.edu> wrote:
Simon Biber <ne**@ralminNOSPAM.cc> wrote:
>#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?


I expect the first %s to print "Fred and George". By the time the
printf function is called, all side effects from the modification
of the array must be completed. I see no undefined behaviour,
it must print "Fred and George or Fred and George\n".

I see no problem evaluating p twice; its value does not change!


You are quite right. I misspoke.

--
Rouben Rostamian
Nov 13 '05 #24

P: n/a
On Sun, 23 Nov 2003 17:22:52 +0100, "cody"
<do*********************@gmx.de> 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.


The order in which the arguments are evaluated is unspecified
behavior, but not undefined.
<<Remove the del for email>>
Nov 13 '05 #25

P: n/a
On 22 Nov 2003 20:18:35 -0800, Ben Pfaff <bl*@cs.stanford.edu> wrote:
CBFalconer <cb********@yahoo.com> 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.


Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.
<<Remove the del for email>>
Nov 13 '05 #26

P: n/a
Barry Schwarz wrote:
Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.


No, the point is that is p is _NOT_ modified, only the memory that p
points to is modified by strcat. Because of that, it doesn't matter
whether the contents of p (the address of the buffer) are evaluated
before or after the call to strcat, the buffer's address will not be
changed.

Nov 13 '05 #27

P: n/a
Barry Schwarz wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote:
CBFalconer <cb********@yahoo.com> 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.


Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.


In fact p is never modified. The storage at which p points IS
modified. Thus the action is well defined, but unexpected. I
think this is one of the few mistakes Ben has made.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #28

P: n/a
On Mon, 24 Nov 2003 09:40:10 -0700, "Kevin P. Fleming"
<kp*******@cox.net> wrote:
Barry Schwarz wrote:
Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.


No, the point is that is p is _NOT_ modified, only the memory that p
points to is modified by strcat. Because of that, it doesn't matter
whether the contents of p (the address of the buffer) are evaluated
before or after the call to strcat, the buffer's address will not be
changed.


Since p is an array and not a pointer, p is being changed.
<<Remove the del for email>>
Nov 13 '05 #29

P: n/a
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Barry Schwarz wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote:
>CBFalconer <cb********@yahoo.com> 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.


Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.


In fact p is never modified. The storage at which p points IS
modified. Thus the action is well defined, but unexpected. I
think this is one of the few mistakes Ben has made.

p is an array and not a pointer so p is being modified.

Since Ben didn't identify why he thought it was undefined behavior,
I'm still waiting for him to chime in.
<<Remove the del for email>>
Nov 13 '05 #30

P: n/a
Barry Schwarz wrote:


Since p is an array and not a pointer, p is being changed.


In the statement given:

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

p is an expression that evaluates to a pointer. In certain contexts, p
would evaluate to an array, but none of those contexts appear in the
example. As far as I can tell, the result is the same as if it had been
done this way:

char *tmp = p;
printf("%s or %s\n", tmp, strcat(tmp, " and George"));

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #31

P: n/a
Barry Schwarz <sc******@deloz.net> wrote:
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Barry Schwarz wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote:
>CBFalconer <cb********@yahoo.com> 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.

Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.


In fact p is never modified. The storage at which p points IS
modified. Thus the action is well defined, but unexpected. I
think this is one of the few mistakes Ben has made.

p is an array and not a pointer so p is being modified.


Arrays are non-modifable lvalues, so p /cannot/ be modified. As
p in the example is used in value context, it is converted to a
pointer to its first element. This pointer isn't (and cannot be)
altered. What /is/ changed are the contents of the array (but it's
not the contents that are passed to printf). These contents are
inspected in the printf function after the arguments have been
evaluated, so the behaviour is well defined.

Consider Kevin's alteration of the example:

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

<snip>

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #32

P: n/a
In <k5********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:
Barry Schwarz <sc******@deloz.net> wrote:
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:
>Barry Schwarz wrote:
>> Ben Pfaff <bl*@cs.stanford.edu> wrote:
>> >CBFalconer <cb********@yahoo.com> 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.
>>
>> Is it really undefined since there are implied sequence points at the
>> call to and return from strcat and p is only modified within strcat.
>
>In fact p is never modified. The storage at which p points IS
>modified. Thus the action is well defined, but unexpected. I
>think this is one of the few mistakes Ben has made.

p is an array and not a pointer so p is being modified.


Arrays are non-modifable lvalues, so p /cannot/ be modified.


Of course it can, just not via direct assignment:

p[0] = 'B';

does modify the p object, which is an array of 100 characters.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #33

P: n/a
In <bp**********@216.39.143.94> Barry Schwarz <sc******@deloz.net> writes:
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Barry Schwarz wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote:
>CBFalconer <cb********@yahoo.com> 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.

Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.
In fact p is never modified. The storage at which p points IS
modified. Thus the action is well defined, but unexpected. I
think this is one of the few mistakes Ben has made.

p is an array and not a pointer so p is being modified.
Yes, but it is modified between two well defined sequence points: the
one preceding the strcat call and the one preceding its return.

No undefined behaviour at all.
Since Ben didn't identify why he thought it was undefined behavior,
I'm still waiting for him to chime in.


To say what? That he goofed?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #34

P: n/a
Da*****@cern.ch (Dan Pop) wrote:
In <k5********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:

<snip>
Arrays are non-modifable lvalues, so p /cannot/ be modified.


Of course it can, just not via direct assignment:

p[0] = 'B';

does modify the p object, which is an array of 100 characters.


Hrmpf. Maybe I should have written: "It is impossible to modify
the pointer p is converted to when used in a value context."

However, to someone with *both* cerebral hemispheres enabled the
meaning of my original claim should've been clear from the context,
which you snipped. ;^)

[unsnip]
IG> As p in the example is used in value context, it is converted to
IG> a pointer to its first element. This pointer isn't (and cannot
IG> be) altered. What /is/ changed are the contents of the array
IG> (but it's not the contents that are passed to printf).

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #35

P: n/a
In <c0********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:
Da*****@cern.ch (Dan Pop) wrote:
In <k5********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:

<snip>
>Arrays are non-modifable lvalues, so p /cannot/ be modified.


Of course it can, just not via direct assignment:

p[0] = 'B';

does modify the p object, which is an array of 100 characters.


Hrmpf. Maybe I should have written: "It is impossible to modify
the pointer p is converted to when used in a value context."

However, to someone with *both* cerebral hemispheres enabled the
meaning of my original claim should've been clear from the context,
which you snipped. ;^)

[unsnip]
IG> As p in the example is used in value context, it is converted to
IG> a pointer to its first element. This pointer isn't (and cannot
IG> be) altered. What /is/ changed are the contents of the array
IG> (but it's not the contents that are passed to printf).


The context doesn't make your statement any less wrong. And the general
context of the discussion was the p *object* (which does get changed in
the code under discussion), not the pointer p decays to when used
in a value context.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #36

P: n/a
Da*****@cern.ch (Dan Pop) wrote:
In <c0********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:
Da*****@cern.ch (Dan Pop) wrote:
In <k5********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:<snip>
>Arrays are non-modifable lvalues, so p /cannot/ be modified.

Of course it can, just not via direct assignment:

p[0] = 'B';

does modify the p object, which is an array of 100 characters.


Hrmpf. Maybe I should have written: "It is impossible to modify
the pointer p is converted to when used in a value context."

However, to someone with *both* cerebral hemispheres enabled the
meaning of my original claim should've been clear from the context,
which you snipped. ;^)

[unsnip]
IG> As p in the example is used in value context, it is converted to
IG> a pointer to its first element. This pointer isn't (and cannot
IG> be) altered. What /is/ changed are the contents of the array
IG> (but it's not the contents that are passed to printf).


The context doesn't make your statement any less wrong.

Maybe we could agree that the wording was wrong, and it didn't
express what I wanted to say.
And the general
context of the discussion was the p *object* (which does get changed in
the code under discussion), not the pointer p decays to when used
in a value context.


Well, right. And since the changes to the object designated by p
are completed before pointers to the first byte of that object are
passed to printf, the construct in question upthread is well defined
in terms of C.

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #37

P: n/a
Dan Pop wrote:
Irrwahn Grausewitz <ir*******@freenet.de> writes:
Da*****@cern.ch (Dan Pop) wrote:
Irrwahn Grausewitz <ir*******@freenet.de> writes:
<snip>

Arrays are non-modifable lvalues, so p /cannot/ be modified.

Of course it can, just not via direct assignment:

p[0] = 'B';

does modify the p object, which is an array of 100 characters.


Hrmpf. Maybe I should have written: "It is impossible to modify
the pointer p is converted to when used in a value context."

However, to someone with *both* cerebral hemispheres enabled the
meaning of my original claim should've been clear from the context,
which you snipped. ;^)

[unsnip]
IG> As p in the example is used in value context, it is converted
IG> to a pointer to its first element. This pointer isn't (and
IG> cannot be) altered. What /is/ changed are the contents of the
IG> array (but it's not the contents that are passed to printf).


The context doesn't make your statement any less wrong. And the
general context of the discussion was the p *object* (which does
get changed in the code under discussion), not the pointer p
decays to when used in a value context.


No - see subject. The context is functions returning extraneous
pointers and the misuse and confusion that can result from using
such, with a side trip into the legitimacy of the example confused
code.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #38

P: n/a
On Tue, 25 Nov 2003 07:31:39 GMT, Kevin Goodsell
<us*********************@neverbox.com> wrote:
Barry Schwarz wrote:


Since p is an array and not a pointer, p is being changed.

In the statement given:

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

p is an expression that evaluates to a pointer. In certain contexts, p
would evaluate to an array, but none of those contexts appear in the


I agree that p evaluates to a pointer in the statement but, after
strcat has returned, the actual contents of p have been modified.
example. As far as I can tell, the result is the same as if it had been
done this way:

char *tmp = p;
printf("%s or %s\n", tmp, strcat(tmp, " and George"));


The one difference is that the contents of tmp have not been modified.

<<Remove the del for email>>
Nov 13 '05 #39

P: n/a
On Tue, 25 Nov 2003 10:46:25 +0100, Irrwahn Grausewitz
<ir*******@freenet.de> wrote:
Barry Schwarz <sc******@deloz.net> wrote:
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:
>Barry Schwarz wrote:
>> Ben Pfaff <bl*@cs.stanford.edu> wrote:
>> >CBFalconer <cb********@yahoo.com> 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.
>>
>> Is it really undefined since there are implied sequence points at the
>> call to and return from strcat and p is only modified within strcat.
>
>In fact p is never modified. The storage at which p points IS
>modified. Thus the action is well defined, but unexpected. I
>think this is one of the few mistakes Ben has made. p is an array and not a pointer so p is being modified.


Arrays are non-modifable lvalues, so p /cannot/ be modified. As


Non-modifiable lvalues cannot be modified by an assignment statement
but arrays are objects and certainly can be modified. In fact, after
strcat returns, the contents of the array p have been modified.
p in the example is used in value context, it is converted to a
pointer to its first element. This pointer isn't (and cannot be)
altered. What /is/ changed are the contents of the array (but it's
not the contents that are passed to printf). These contents are
No disagreement.
inspected in the printf function after the arguments have been
evaluated, so the behaviour is well defined.
I don't disagree but I'm still waiting for Ben to tell us what
prompted his original comment.

Consider Kevin's alteration of the example:

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

<snip>

Regards


<<Remove the del for email>>
Nov 13 '05 #40

P: n/a
On 25 Nov 2003 16:23:30 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <bp**********@216.39.143.94> Barry Schwarz <sc******@deloz.net> writes:
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Barry Schwarz wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote:
>CBFalconer <cb********@yahoo.com> 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.

Is it really undefined since there are implied sequence points at the
call to and return from strcat and p is only modified within strcat.

In fact p is never modified. The storage at which p points IS
modified. Thus the action is well defined, but unexpected. I
think this is one of the few mistakes Ben has made.

p is an array and not a pointer so p is being modified.


Yes, but it is modified between two well defined sequence points: the
one preceding the strcat call and the one preceding its return.

No undefined behaviour at all.
Since Ben didn't identify why he thought it was undefined behavior,
I'm still waiting for him to chime in.


To say what? That he goofed?


Possibly; it wouldn't be the first time for most of us. Or maybe to
indicate he was thinking of something else.
<<Remove the del for email>>
Nov 13 '05 #41

P: n/a
Barry Schwarz <sc******@deloz.net> wrote:
On Tue, 25 Nov 2003 10:46:25 +0100, Irrwahn Grausewitz
<ir*******@freenet.de> wrote:
Arrays are non-modifable lvalues, so p /cannot/ be modified. As


Non-modifiable lvalues cannot be modified by an assignment statement
but arrays are objects and certainly can be modified. In fact, after
strcat returns, the contents of the array p have been modified.


Agreed.

Regards,
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #42

P: n/a
In <sn********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:
Da*****@cern.ch (Dan Pop) wrote:
And the general
context of the discussion was the p *object* (which does get changed in
the code under discussion), not the pointer p decays to when used
in a value context.


Well, right. And since the changes to the object designated by p
are completed before pointers to the first byte of that object are
passed to printf, the construct in question upthread is well defined
in terms of C.


This was also my conclusion, posted higher upthread. The change to the
value of the p object is delimited by two well defined sequence points.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #43

P: n/a
In <bq**********@216.39.143.67> Barry Schwarz <sc******@deloz.net> writes:
On 25 Nov 2003 16:23:30 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <bp**********@216.39.143.94> Barry Schwarz <sc******@deloz.net> writes:
On Mon, 24 Nov 2003 18:47:31 GMT, CBFalconer <cb********@yahoo.com>
wrote:

Barry Schwarz wrote:
> Ben Pfaff <bl*@cs.stanford.edu> wrote:
> >CBFalconer <cb********@yahoo.com> 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.
>
> Is it really undefined since there are implied sequence points at the
> call to and return from strcat and p is only modified within strcat.

In fact p is never modified. The storage at which p points IS
modified. Thus the action is well defined, but unexpected. I
think this is one of the few mistakes Ben has made.

p is an array and not a pointer so p is being modified.


Yes, but it is modified between two well defined sequence points: the
one preceding the strcat call and the one preceding its return.

No undefined behaviour at all.
Since Ben didn't identify why he thought it was undefined behavior,
I'm still waiting for him to chime in.


To say what? That he goofed?


Possibly; it wouldn't be the first time for most of us. Or maybe to
indicate he was thinking of something else.


Is there anything else to think about as a source of undefined behaviour?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #44

P: n/a
Da*****@cern.ch (Dan Pop) wrote:
In <sn********************************@4ax.com> Irrwahn Grausewitz <ir*******@freenet.de> writes:
Da*****@cern.ch (Dan Pop) wrote:
And the general
context of the discussion was the p *object* (which does get changed in
the code under discussion), not the pointer p decays to when used
in a value context.


Well, right. And since the changes to the object designated by p
are completed before pointers to the first byte of that object are
passed to printf, the construct in question upthread is well defined
in terms of C.


This was also my conclusion, posted higher upthread. The change to the
value of the p object is delimited by two well defined sequence points.


Which is what I tried to express (possibly using inapproriate terms)
just before you chimed in. Seems that we entirely agree now. :-)

Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #45

This discussion thread is closed

Replies have been disabled for this discussion.