472,119 Members | 1,623 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,119 software developers and data experts.

strcpy - my implementation

I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
/* My version of "strcpy - a C Library Function */

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

enum { ARRSIZE = 101 };

char* my_strcpy( char*, char* );

int main( int argc, char** argv )
{
char* pc;

char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
if( 2 != argc )
{
perror("USAGE: ./exec \" your input \"\n");
exit( EXIT_FAILURE );
}
else
{
strcpy( arr_in , argv[1] );
}

pc = my_strcpy( arr_out, arr_in );

while( *pc )
{
printf("*pc = %c\n", *pc++);
}

return EXIT_SUCCESS;
}

char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
=============== OUTPUT ======================

[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra check_STRCPY.c
[arnuld@dune ztest]$ ./a.out like
*pc = l
*pc = i
*pc = k
*pc = e
[arnuld@dune ztest]$

It works fine without troubles. Now if you change the last return call in
my_strcpy from "return pc" to return "return arr_out", then while loop in
main() will not print anything at all. I really did not understand it.
Using thr array name will give a pointer to its 1st element but int htis
case it is giving a pointer to its last element. Why ? Thats why I
introduced the extra "char* pc" in first place.


--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is Blocked. Reason: Excessive Spamming

Sep 8 '08 #1
77 8099
Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
That should be: char *strcpy(char *dest, const char *src);
char* pc;
pc = arr_out;
while( (*arr_out++ = *arr_in++) ) ;
return pc;
}
It works fine without troubles. Now if you change the last return call
in my_strcpy from "return pc" to return "return arr_out", then while
loop in main() will not print anything at all. I really did not
understand it. Using thr array name will give a pointer to its 1st
element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.
arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
case, at the end of the function it will point past the end of the string.

Your implementation is much slower than what that would be used in almost
any real c library, because it copies one byte at a time. If you know
something more about the way the target processor works than the C
standard tells you, then you can copy several bytes at a time using (for
example) int.

HTH
viza
Sep 8 '08 #2
arnuld said:
I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
/* My version of "strcpy - a C Library Function */

#include <stdio.h>
#include <stdlib.h>
I understand that you might need these for testing purposes...
#include <unistd.h>
....but why on earth do you need this non-standard header for testing an
implementation of a standard and rather simple C function?
#include <string.h>
Strange that you should need this, but okay.
enum { ARRSIZE = 101 };

char* my_strcpy( char*, char* );
Better: char *my_strcpy(char *, const char *);
>
int main( int argc, char** argv )
{
char* pc;

char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
Or just:

char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

which saves you two memset calls.
if( 2 != argc )
{
perror("USAGE: ./exec \" your input \"\n");
exit( EXIT_FAILURE );
}
else
{
strcpy( arr_in , argv[1] );
What if argv[1] is longer than 100 bytes? You should test for this.

<snip>
char* my_strcpy( char* arr_out, char* arr_in )
Better: char *my_strcpy(char * arr_out, const char *arr_in)
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
How is this *your* implementation? It isn't significantly different from
the implementation on p105 of K&R2, with names changed to protect the
innocent and a return value added to get a closer match to ISO strcpy.

<snip>
It works fine without troubles. Now if you change the last return call in
my_strcpy from "return pc" to return "return arr_out", then while loop in
main() will not print anything at all.
arr_out is badly named. In my_strcpy, it's not an array, but a pointer.

Consider what value that pointer has at the time you've completed the loop.
To which byte is it pointing? What value does that byte have? And
consequently, if you return it to main and capture that pointer value in
pc = my_strcpy(arr_out, arr_in), to what byte is pc pointing?

You would find it easier to learn and we would find it easier to explain if
you chose different names in called functions from those in calling
functions. When discussing your program, I can't refer to 'pc' without
saying which pc I mean. Nor can I refer to arr_in or arr_out without
saying which I mean. Had you used different names in my_strcpy, it would
have made discussion easier.
I really did not understand it.
Using thr array name will give a pointer to its 1st element
Yes. And that's what my_strcpy's arr_in is - a copy of a pointer to the
first element of an array. But then *you* change the value of that
pointer.
but int htis
case it is giving a pointer to its last element. Why ?
If you change an object's value, you should not be surprised if that
object's value changes.

Thats why I introduced the extra "char* pc" in first place.
Yes. It's necessary in this case. Well, there is another way round,
actually:

char *my_strcpy(char *target, const char *source)
{
size_t i = 0;
while(target[i] = source[i])
{
++i;
}

return target;
}

which avoids the extra pointer, but only at the expense of an extra size_t.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #3
arnuld wrote:
>
char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
As has been pointed out elsewhere, the source pointer should be const
and the names don't make sense. The inner parentheses in the while loop
are superfluous.
>
It works fine without troubles. Now if you change the last return call in
my_strcpy from "return pc" to return "return arr_out", then while loop in
main() will not print anything at all. I really did not understand it.
Using thr array name will give a pointer to its 1st element but int htis
case it is giving a pointer to its last element. Why ? Thats why I
introduced the extra "char* pc" in first place.
Because you have incremented it to point the the '\0' at the end of the
string.

--
Ian Collins.
Sep 8 '08 #4
viza <to******@gm-il.com.obviouschange.invalidwrites:
Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
>/* My version of "strcpy - a C Library Function */
>char* my_strcpy( char* arr_out, char* arr_in ) {

That should be: char *strcpy(char *dest, const char *src);
Oh for goodness sake.
>
> char* pc;
pc = arr_out;
while( (*arr_out++ = *arr_in++) ) ;
return pc;
}
>It works fine without troubles. Now if you change the last return call
in my_strcpy from "return pc" to return "return arr_out", then while
loop in main() will not print anything at all. I really did not
understand it. Using thr array name will give a pointer to its 1st
element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.

arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
If you increment it once it will be a pointer to a later address in
memory...
case, at the end of the function it will point past the end of the
string.
So what?
>
Your implementation is much slower than what that would be used in
almost
Much slower?
any real c library, because it copies one byte at a time. If you know
something more about the way the target processor works than the C
standard tells you, then you can copy several bytes at a time using (for
example) int.

HTH
viza
I would be interested to hear how you would do this in standard C.
Sep 8 '08 #5
Richard wrote:
viza <to******@gm-il.com.obviouschange.invalidwrites:
>Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
>>/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
>That should be: char *strcpy(char *dest, const char *src);

Oh for goodness sake.
Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
>>element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.
>arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
case, at the end of the function it will point past the end of the
string.

So what?
He's answering the question, boy you are dense tonight..

--
Ian Collins.
Sep 8 '08 #6
Ian Collins <ia******@hotmail.comwrites:
Richard wrote:
>viza <to******@gm-il.com.obviouschange.invalidwrites:
>>Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
>>That should be: char *strcpy(char *dest, const char *src);

Oh for goodness sake.
Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
I was referring to the name change.
>
>>>element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.
>>arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
case, at the end of the function it will point past the end of the
string.

So what?
He's answering the question, boy you are dense tonight..
I am pointing out that it has zero impact. So nothing to worry
about. But I could have, and should have, been more explicit.
Sep 8 '08 #7
On Sep 8, 11:21 am, Ian Collins <ian-n...@hotmail.comwrote:
Richard wrote:
viza <tom.v...@gm-il.com.obviouschange.invalidwrites:
Hi
On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
That should be: char *strcpy(char *dest, const char *src);
Oh for goodness sake.

Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
No, it's wrong.
It's C code, not a C implementation, therefore it shouldn't have the
name strcpy. (a hint that it's C code is that he includes several
standard header files, ignoring <unistd.hand that he has main there)
Sep 8 '08 #8

"Ian Collins" <ia******@hotmail.comwrote in message
news:6i************@mid.individual.net...
arnuld wrote:
>>
char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
The inner parentheses in the while loop
are superfluous.
I thought this was sometimes used to stop the compiler warning about using
"=" instead of "==".

--
Bartc

Sep 8 '08 #9
"arnuld" <su*****@invalid.addresswrote in message
news:pa****************************@invalid.addres s...
>I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;
if (arr_out==NULL||arr_in==NULL)return "";

Testing for null strings might be useful; either return empty string or
abort. But not everyone agrees.
pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;
If you're interested in speed you might like to test your version against
the standard strcpy, for various lengths of strings and copying a few
million times.

You might then also like to test a version using strlen() and memcpy().

--
Bartc

Sep 8 '08 #10
Bartc said:
>
"Ian Collins" <ia******@hotmail.comwrote in message
news:6i************@mid.individual.net...
>arnuld wrote:
>>>
<snip>
>> while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
>The inner parentheses in the while loop
are superfluous.

I thought this was sometimes used to stop the compiler warning about
using "=" instead of "==".
Right, and in that respect the parentheses are not superfluous in code
intended to be compiled by implementations that recognise that construct
as having that meaning. They /are/ superfluous from a C perspective,
because they can be removed without affecting the semantics of the code.
So whether or not they are truly superfluous really depends on what you
mean by "superfluous".

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #11
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};
What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
Sep 8 '08 #12
Richard Heathfield wrote:
arnuld said:
>char* my_strcpy( char* arr_out, char* arr_in )

Better: char *my_strcpy(char * arr_out, const char *arr_in)
>{
char* pc;

pc = arr_out;
You could change that to

char *const pc = arr_out;
> while( (*arr_out++ = *arr_in++) ) ;
/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {

/*
** There are some coding guidelines against writing
** an entire loop with only an empty statement on one line.
** Some programmers, including myself,
** always use a compound statement
** with an if statement or a loop statement.
*/
;
}
>>
return pc;
}
http://www.psgd.org/paul/docs/cstyle/cstyle.htm
http://www.psgd.org/paul/docs/cstyle/cstyle08.htm

--
pete
Sep 8 '08 #13
Sjoerd wrote:
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
> char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
Your expectation is incorrect. If you explicitly initialize any elements
of an array or any members of a structure, all of the remaining array
elements or structure members are implicitly zero-initialized.
Sep 8 '08 #14
Sjoerd wrote:
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
> char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
That the way it seems
if you don't know the relevant parts of the C language.

char arr_in[ARRSIZE] = "";

is yet another way to initialize the entire array to null characters.

A short initializer, sets the remaining elements
as though they were each initilzed with {0}.

char array[10] = {'A'};
or
char array[10] = "A";

gives you an array with one element equal to ('A'),
followed by nine array elements, each equal to ('\0').

--
pete
Sep 8 '08 #15
Richard Heathfield <rj*@see.sig.invalidwrites:
arnuld said:
>I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
[...]
>>
int main( int argc, char** argv )
{
char* pc;

char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );

Or just:

char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

which saves you two memset calls.
Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.

[snip]
>{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}

How is this *your* implementation? It isn't significantly different from
the implementation on p105 of K&R2, with names changed to protect the
innocent and a return value added to get a closer match to ISO strcpy.
It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code. I suspect if you put 100 C programmers
in clean rooms and asked them to write an implementation of strcpy,
you'd only get about three essentially different versions, and this is
one of them. K&R is probably the most memorable appearance of the
`*p++ = *q++' idiom, but just because one saw it there and continues
to use it doesn't make one a plagiarist. It's a textbook, after all.
Sep 8 '08 #16
Nate Eldredge <na**@vulcan.lanwrites:
Richard Heathfield <rj*@see.sig.invalidwrites:
>arnuld said:
>>I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
[...]
>>>
int main( int argc, char** argv )
{
char* pc;

char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );

Or just:

char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

which saves you two memset calls.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
You think
> char arr_in[ARRSIZE] = {0};
camouflages it? To be honest after spending time in c.l.c I get the
heebygeebies whenever I see memset with arrays - I'm not really sure
whats a character anymore, whats an array etc. I wonder if that memory
has "alignment issues" with "special pointers" etc etc. I used to think
of them as blocks of memory and all my programs just worked. c.l.c put
paid to that... :-;
>
[snip]
>>{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}

How is this *your* implementation? It isn't significantly different from
the implementation on p105 of K&R2, with names changed to protect the
innocent and a return value added to get a closer match to ISO strcpy.

It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code. I suspect if you put 100 C programmers
in clean rooms and asked them to write an implementation of strcpy,
you'd only get about three essentially different versions, and this is
one of them. K&R is probably the most memorable appearance of the
`*p++ = *q++' idiom, but just because one saw it there and continues
to use it doesn't make one a plagiarist. It's a textbook, after all.
You would be amazed at how few would actually do it this way. There are
many people out there who discourage such stuff. I even read here once
that it "misuses C" ... the mind boggles. I have seen many code bases
where you hardly ever see a pointer used in its natural habitat. A
crying shame IMO.

Sep 8 '08 #17
Nate Eldredge <na**@vulcan.lanwrites:
[...]
Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
[...]

Why do auto arrays have to be zeroed? There's certainly no C
requirement for this; any such requirement would have to be
system-specific.

Of course an implementation is certainly allowed to zero auto objects.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 8 '08 #18
On Sep 8, 7:47 pm, Nate Eldredge <n...@vulcan.lanwrote:
Richard Heathfield <r...@see.sig.invalidwrites:
arnuld said:
char arr_in[ARRSIZE];
char arr_out[ARRSIZE];
memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
Or just:
char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};
which saves you two memset calls.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
Nonsense. memset sets the bit pattern to 0. {0} Sets pointers to NULL,
floating point objects to 0.0, integers to 0, etc.
They are not equivalent.
Sep 8 '08 #19
On Sep 8, 7:47 pm, Nate Eldredge <n...@vulcan.lanwrote:
Richard Heathfield <r...@see.sig.invalidwrites:
arnuld said:
char arr_in[ARRSIZE];
char arr_out[ARRSIZE];
memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
Or just:
char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};
which saves you two memset calls.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
Initializing an object to {0} is not the same with memset(&object, 0,
sizeof object);

(if this message appears twice, I apologise, but it was googlegroups
fault)

Sep 8 '08 #20
Nate Eldredge said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>arnuld said:
<snip>
>>>
char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );

Or just:

char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

which saves you two memset calls.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway.
Fine, but that's the implementation's problem. The saving is in the source
code: economy of expression.
My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
It isn't very good camouflage, though, since any experienced C programmer
will recognise it for what it is. It's just a more elegant way to write
the code. We don't write char foo[8] = { 'H', 'e', 'l', 'l', 'o', '\0',
'\0', '\0' } just because it makes explicit the fact that eight characters
are being copied into the array. We write char foo[8] = "Hello", and trust
that competent programmers will understand.
>
[snip]
>>{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}

How is this *your* implementation? It isn't significantly different from
the implementation on p105 of K&R2, with names changed to protect the
innocent and a return value added to get a closer match to ISO strcpy.

It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code.
I don't think it would be reasonable to call it plagiarism, since it's
blindingly obvious to all concerned that it's basically the K&R2 code. I
was just pointing out that "my own implementation" wasn't really the right
way to describe it.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #21
vi******@gmail.com writes:
On Sep 8, 7:47 pm, Nate Eldredge <n...@vulcan.lanwrote:
>Richard Heathfield <r...@see.sig.invalidwrites:
arnuld said:
char arr_in[ARRSIZE];
char arr_out[ARRSIZE];
> memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
Or just:
char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};
which saves you two memset calls.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.

Nonsense. memset sets the bit pattern to 0. {0} Sets pointers to NULL,
floating point objects to 0.0, integers to 0, etc.
They are not equivalent.
Correct.

On the other hand, an implementation is free to use memset() to
zero-initialize arbitrary objects if the author happens to know that
all-bits-zero is a valid representation of 0 for all the appropriate
types.

On the other other hand, such an initialization is not required for
auto objects.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 8 '08 #22
Keith Thompson said:
Nate Eldredge <na**@vulcan.lanwrites:
[...]
>Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
[...]

Why do auto arrays have to be zeroed?
I think you have misunderstood him; he means that the construct:

char foo[N] = {0};

would require the dynamic zeroing of the array only if it's an auto array,
*not* if it has static storage duration.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #23
vi******@gmail.com said:
On Sep 8, 7:47 pm, Nate Eldredge <n...@vulcan.lanwrote:
>Richard Heathfield <r...@see.sig.invalidwrites:
arnuld said:
char arr_in[ARRSIZE];
char arr_out[ARRSIZE];
> memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
Or just:
char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};
which saves you two memset calls.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.

Nonsense. memset sets the bit pattern to 0. {0} Sets pointers to NULL,
floating point objects to 0.0, integers to 0, etc.
They are not equivalent.
They are equivalent for arrays of integers (such as char), so it is not
nonsense in this particular case. I don't agree with him, but he's not
actually talking nonsense.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #24
Keith Thompson <ks***@mib.orgwrites:
Nate Eldredge <na**@vulcan.lanwrites:
[...]
>Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
[...]

Why do auto arrays have to be zeroed? There's certainly no C
requirement for this; any such requirement would have to be
system-specific.
This was in reference to a definition (which you snipped) of the form

int main(void) {
char arr_in[ARRSIZE] = {0};
...
}

with an explicit initializer, in which case the implementation is
certainly required to zero the array. Since it's auto, it most likely
has to do it at runtime.
Sep 8 '08 #25
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
>Nate Eldredge <na**@vulcan.lanwrites:
[...]
>>Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
[...]

Why do auto arrays have to be zeroed?

I think you have misunderstood him; he means that the construct:

char foo[N] = {0};

would require the dynamic zeroing of the array only if it's an auto array,
*not* if it has static storage duration.
You're probably right. I saw an emphasis on "zeroed out"; the actual
emphasis was on "at runtime".

And in the discussion about whether memset is appropriate,
stylistically or logically, I also missed the fact that the objects in
question are arrays of char, so using memset to zero them is perfectly
appropriate.

But I'd still prefer
char foo[N] = { 0 };
or, if it's intended to hold a string:
char foo[N] = "";
or, if I were concerned about the time wasted zeroing the entire array:
char foo[N];
foo[0] = '\0';

The latter, of course, is not equivalent to the others or to the
memset call, but the difference matters only if you're going to be
accessing characters past the first '\0'.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 8 '08 #26
arnuld wrote:
>
I have created my own implementation of strcpy library function.
I would like to have comments for improvements:

/* My version of "strcpy - a C Library Function */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
This doesn't exist in standard C.
#include <string.h>
Besides which, writing replacement functions with the same name is
forbidden by the C standard. So don't do it except for specific
systems after fully appreciating the inclusion. However, consider
using strlcpy (and strlcat), which use a reserved name (and you can
change that). Full source in purely standard C, docs, etc.
available at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 8 '08 #27
Ian Collins wrote:
Richard wrote:
>viza <to******@gm-il.com.obviouschange.invalidwrites:
>>arnuld wrote:

/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {

That should be: char *strcpy(char *dest, const char *src);

Oh for goodness sake.

Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
No he isn't. In fact, both are wrong. The definition is:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);

Description

[#2] The strcpy function copies the string pointed to by s2
(including the terminating null character) into the array
pointed to by s1. If copying takes place between objects
that overlap, the behavior is undefined.

Returns

[#3] The strcpy function returns the value of s1.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 8 '08 #28
pete wrote:
>arnuld said:
.... snip ...
>
>> while( (*arr_out++ = *arr_in++) ) ;

/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless. It already tests the value of the underlined
expression for zero/non-zero.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 8 '08 #29
CBFalconer said:
pete wrote:
>>arnuld said:
... snip ...
>>
>>> while( (*arr_out++ = *arr_in++) ) ;

/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless.
I disagree. An explicit comparison against 0 is pointless in terms of the
code, yes, but it's not pointless in terms of self-documentation, and it
certainly isn't silly.
It already tests the value of the underlined
expression for zero/non-zero.
Do you think 'pete' doesn't already know that?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #30
CBFalconer wrote, On 08/09/08 22:02:
arnuld wrote:
>I have created my own implementation of strcpy library function.
I would like to have comments for improvements:

/* My version of "strcpy - a C Library Function */
<snip>
>#include <string.h>

Besides which, writing replacement functions with the same name is
forbidden by the C standard.
He did not. Read the original message to which you just replied again.
Take specific note of the identifiers starting with "my_" and the lack
of identifiers starting with "str".
So don't do it except for specific
systems after fully appreciating the inclusion.
He didn't.
However, consider
using strlcpy (and strlcat), which use a reserved name (and you can
<snip>

What has that got to do with the price of fish? Apart from the fact that
having complained at arnuld for doing something he didn't you are
suggesting that he use code where you *did* do what you (incorrectly)
complained at him for doing.
--
Flash Gordon
Sep 8 '08 #31
Richard Heathfield <rj*@see.sig.invalidwrites:
CBFalconer said:
>pete wrote:
>>>arnuld said:
... snip ...
>>>
while( (*arr_out++ = *arr_in++) ) ;

/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless.

I disagree. An explicit comparison against 0 is pointless in terms of the
code, yes, but it's not pointless in terms of self-documentation, and it
certainly isn't silly.
I disagree. It is long winded and unnecessary. "while(*d++=*s++){}" is a
corner stone of C programming and understanding. Adding the comparison
does nothing to aid the understanding. A style thing maybe.
Sep 8 '08 #32
Richard wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
>CBFalconer said:
>>pete wrote:
arnuld said:
... snip ...
> while( (*arr_out++ = *arr_in++) ) ;
/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless.
I disagree. An explicit comparison against 0 is pointless in terms of the
code, yes, but it's not pointless in terms of self-documentation, and it
certainly isn't silly.

I disagree. It is long winded and unnecessary. "while(*d++=*s++){}" is a
corner stone of C programming and understanding. Adding the comparison
does nothing to aid the understanding. A style thing maybe.
It is a style thing.
The one and only circumstance
under which I will ommit the explicit comparison against zero
(assuming that zero is what the expression is being compared against),
is when the expression is conceptually boolean in nature,
such as something like:

while (isspace(*c)) {
--
pete
Sep 8 '08 #33
pete <pf*****@mindspring.comwrites:
Richard wrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>CBFalconer said:

pete wrote:
>arnuld said:
... snip ...
>> while( (*arr_out++ = *arr_in++) ) ;
/* I would go even further than just extra parentheses: */
>
while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless.
I disagree. An explicit comparison against 0 is pointless in terms
of the code, yes, but it's not pointless in terms of
self-documentation, and it certainly isn't silly.

I disagree. It is long winded and unnecessary. "while(*d++=*s++){}" is a
corner stone of C programming and understanding. Adding the comparison
does nothing to aid the understanding. A style thing maybe.

It is a style thing.
The one and only circumstance
under which I will ommit the explicit comparison against zero
(assuming that zero is what the expression is being compared against),
is when the expression is conceptually boolean in nature,
such as something like:

while (isspace(*c)) {
Could you explain why C does not effectively make the while() above
"boolean" in nature and will not always do so?
Sep 8 '08 #34
Richard wrote:
pete <pf*****@mindspring.comwrites:
>Richard wrote:
>>Richard Heathfield <rj*@see.sig.invalidwrites:

CBFalconer said:

pete wrote:
>>arnuld said:
... snip ...
>>> while( (*arr_out++ = *arr_in++) ) ;
>/* I would go even further than just extra parentheses: */
>>
> while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^
>
Silly and pointless.
I disagree. An explicit comparison against 0 is pointless in terms
of the code, yes, but it's not pointless in terms of
self-documentation, and it certainly isn't silly.
I disagree. It is long winded and unnecessary. "while(*d++=*s++){}" is a
corner stone of C programming and understanding. Adding the comparison
does nothing to aid the understanding. A style thing maybe.
It is a style thing.
The one and only circumstance
under which I will ommit the explicit comparison against zero
(assuming that zero is what the expression is being compared against),
is when the expression is conceptually boolean in nature,
such as something like:

while (isspace(*c)) {

Could you explain why C does not effectively make the while() above
"boolean" in nature and will not always do so?
Any expression in while parentheses becomes boolean.
I omit the expilicit comparison for test expressions
which are conceptually boolean even when they are
not test expressions in a while loop.

The value of isspace(c) is described this way:
N869
7.4.1 Character testing functions
[#1] The functions in this subclause return nonzero (true)
if and only if the value of the argument c conforms to that
in the description of the function.

That wouldn't be a good way to describe
the value of (*arr_out++ = *arr_in++).

You could have
while ((*arr_out++ = *arr_in++) != '\0') {
or
while ((*arr_out++ = *arr_in++) != '\n') {
or something else, depending on what you want to do.
--
pete
Sep 8 '08 #35
pete <pf*****@mindspring.comwrites:
Richard wrote:
>pete <pf*****@mindspring.comwrites:
>>Richard wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:

CBFalconer said:
>
>pete wrote:
>>>arnuld said:
>... snip ...
>>>> while( (*arr_out++ = *arr_in++) ) ;
>>/* I would go even further than just extra parentheses: */
>>>
>> while ((*arr_out++ = *arr_in++) != '\0') {
> ^^^^^^^^^^^^^^^^^^^^^^
>>
>Silly and pointless.
I disagree. An explicit comparison against 0 is pointless in terms
of the code, yes, but it's not pointless in terms of
self-documentation, and it certainly isn't silly.
I disagree. It is long winded and unnecessary. "while(*d++=*s++){}" is a
corner stone of C programming and understanding. Adding the comparison
does nothing to aid the understanding. A style thing maybe.
It is a style thing.
The one and only circumstance
under which I will ommit the explicit comparison against zero
(assuming that zero is what the expression is being compared against),
is when the expression is conceptually boolean in nature,
such as something like:

while (isspace(*c)) {

Could you explain why C does not effectively make the while() above
"boolean" in nature and will not always do so?

Any expression in while parentheses becomes boolean.
Yes. And what does \0 become in that case?
I omit the expilicit comparison for test expressions
which are conceptually boolean even when they are
not test expressions in a while loop.

The value of isspace(c) is described this way:
N869
7.4.1 Character testing functions
[#1] The functions in this subclause return nonzero (true)
if and only if the value of the argument c conforms to that
in the description of the function.

That wouldn't be a good way to describe
the value of (*arr_out++ = *arr_in++).
Because that is not an implementation of isspace?
>
You could have
while ((*arr_out++ = *arr_in++) != '\0') {
or
while ((*arr_out++ = *arr_in++) != '\n') {
or something else, depending on what you want to do.
Erm, we are talking about the nul character. or are we? I lose track of
zero, nil, \0 etc.
Sep 9 '08 #36
Richard<rg****@gmail.comwrites:
pete <pf*****@mindspring.comwrites:
>Richard wrote:
>>Richard Heathfield <rj*@see.sig.invalidwrites:

CBFalconer said:

pete wrote:
>>arnuld said:
... snip ...
>>> while( (*arr_out++ = *arr_in++) ) ;
>/* I would go even further than just extra parentheses: */
>>
> while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^
>
Silly and pointless.
I disagree. An explicit comparison against 0 is pointless in terms
of the code, yes, but it's not pointless in terms of
self-documentation, and it certainly isn't silly.

I disagree. It is long winded and unnecessary. "while(*d++=*s++){}" is a
corner stone of C programming and understanding. Adding the comparison
does nothing to aid the understanding. A style thing maybe.

It is a style thing.
The one and only circumstance
under which I will ommit the explicit comparison against zero
(assuming that zero is what the expression is being compared against),
is when the expression is conceptually boolean in nature,
such as something like:

while (isspace(*c)) {

Could you explain why C does not effectively make the while() above
"boolean" in nature and will not always do so?
It does, of course; that's not the point.

Since I share pete's opinion on this style issue, I'll try to explain.

When I write an if or while statement, I prefer to use an expression
that is *conceptually* boolean. By "conceptually boolean", I mean
that the value of the expression can be thought of as either true or
false, and carries no additional information.

For example, if I'm examining the value of a character, the following
are equivalent:
if (c) { ... }
if (c != '\0') { ... }
I prefer to write the latter, because the value of c by itself isn't
just a true or false value, but the result of the "!=" operator is.

Similarly, I would write
if (strcmp(s1, s2) != 0) { ... }
rather than
if (!strcmp(s1, s2)) { ... }

and I would write
if ((ptr = malloc(N)) != NULL) { ... }
rather than
if (ptr = malloc(N)) { ... }

and so forth.

I'm perfectly well aware (as is pete, I'm sure) that in each case the
two forms are precisely equivalent, and will most likely result in
identical generated code. I'm also aware that some C programmers
(including, if I'm not mistaken, Kernighan and Ritchie themselves)
prefer the terser forms and consider the forms that I prefer to be too
verbose. I don't necessarily think that preference is wrong, I just
don't share it. Finally, I don't have any real difficulty
understanding either form; it might sometimes take me a marginally
longer time to understand something in the shorter form, but it's not
really significant.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '08 #37
Richard wrote:
Erm, we are talking about the nul character. or are we?
We were talking about which kind of expressions
I compare explicitly to zero
and which kind of expressions
I don't explicitly compare to zero.

--
pete
Sep 9 '08 #38
Richard wrote:
Erm, we are talking about the nul character. or are we?
We were talking about which kind of expressions
I compare explicitly to zero
and which kind of expressions
I don't explicitly compare to zero.

--
pete
Sep 9 '08 #39
Richard Heathfield wrote:
CBFalconer said:
>pete wrote:
>>>arnuld said:
... snip ...
>>>
while( (*arr_out++ = *arr_in++) ) ;

/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless.

I disagree. An explicit comparison against 0 is pointless in
terms of the code, yes, but it's not pointless in terms of
self-documentation, and it certainly isn't silly.
>It already tests the value of the underlined
expression for zero/non-zero.

Do you think 'pete' doesn't already know that?
You forget the destination of Usenet messages. They are public,
not person to person. Do you conceive that all non-petes ALL know
that?

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 9 '08 #40
pete wrote:
Richard wrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>CBFalconer said:
pete wrote:
>arnuld said:
>>
... snip ...
>> while( (*arr_out++ = *arr_in++) ) ;
/* I would go even further than just extra parentheses: */
>
while ((*arr_out++ = *arr_in++) != '\0') {
^^^^^^^^^^^^^^^^^^^^^^

Silly and pointless.

I disagree. An explicit comparison against 0 is pointless in
terms of the code, yes, but it's not pointless in terms of
self-documentation, and it certainly isn't silly.

I disagree. It is long winded and unnecessary.
"while (*d++ = *s++) {}" is a corner stone of C programming and
understanding. Adding the comparison does nothing to aid the
understanding. A style thing maybe.
However I do not agree with the blank suppression you used, which I
have removed in the above paragraph.
>
It is a style thing. The one and only circumstance under which I
will ommit the explicit comparison against zero (assuming that
zero is what the expression is being compared against), is when
the expression is conceptually boolean in nature, such as
something like:

while (isspace(*c)) {
Note that isspace returns an int, as does the assignment to
*arr_out. Even in C99 with a defined _Bool type, that remains
true.

7.4.1.9 The isspace function

Synopsis
[#1]
#include <ctype.h>
int isspace(int c);

However, I do agree that it is a style thing, and not worth arguing
over. However I reserve the right to state my own preferances.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 9 '08 #41
pete wrote:
>
.... snip ...
>
The value of isspace(c) is described this way: (N869)

7.4.1 Character testing functions
[#1] The functions in this subclause return nonzero (true)
if and only if the value of the argument c conforms to
that in the description of the function.

That wouldn't be a good way to describe
the value of (*arr_out++ = *arr_in++).

You could have
while ((*arr_out++ = *arr_in++) != '\0') {
or
while ((*arr_out++ = *arr_in++) != '\n') {
or something else, depending on what you want to do.
Or you could simply say:

*arr_in has the value 0 when arr_in points to a string
terminating '\0' char.

I know what you mean, but I still maintain it is pointless. The
governing factor is the zeroness or non-zeroness of the term,
whatever that may be. Or the NULLness of the pointer.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 9 '08 #42
Keith Thompson wrote:
>
.... snip ...
>
For example, if I'm examining the value of a character, the
following are equivalent:
if (c) { ... }
if (c != '\0') { ... }
I prefer to write the latter, because the value of c by itself
isn't just a true or false value, but the result of the "!="
operator is.
I disagree. The (c) expression worries only about whether the
character is or is not something with a zero value. The (c !=
'\0') expression expressly converts that zeroness into either the
value 0 or the value 1 before testing. Optimization may affect
this.

I would normally expect the second expression to generate larger
code than does the first, with optimization disabled.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 9 '08 #43
CBFalconer said:
Richard Heathfield wrote:
>CBFalconer said:
<snip>
>>
>>It already tests the value of the underlined
expression for zero/non-zero.

Do you think 'pete' doesn't already know that?

You forget the destination of Usenet messages. They are public,
not person to person. Do you conceive that all non-petes ALL know
that?
Does everyone really expect every poster to explain every nuance of every
aspect of C they use in every article?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 9 '08 #44
Flash Gordon wrote:
CBFalconer wrote, On 08/09/08 22:02:
.... snip ...
>
>However, consider using strlcpy (and strlcat), which use a
reserved name (and you can change that)

<snip>

What has that got to do with the price of fish? Apart from the
fact that having complained at arnuld for doing something he
didn't you are suggesting that he use code where you *did* do
what you (incorrectly) complained at him for doing.
I accept the wet noodle lashing for the incorrect complaint.
However, notice that replacing strcpy is different than adding
strlcpy. strcpy exists in the current libraries. strlcpy does
not. Any possible problem is somewhere in the future. And, as I
pointed out, those names are alterable in the source code.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 9 '08 #45
CBFalconer said:
Keith Thompson wrote:
>>
... snip ...
>>
For example, if I'm examining the value of a character, the
following are equivalent:
if (c) { ... }
if (c != '\0') { ... }
I prefer to write the latter, because the value of c by itself
isn't just a true or false value, but the result of the "!="
operator is.

I disagree.
With what? With Keith's claim to prefer one style over the other? If so,
what makes you think you know better than he does which style he prefers?
Or are you disagreeing with his claim that the value of c by itself isn't
just a true or false value? If so, please explain why it isn't also a
numeric value.
The (c) expression worries only about whether the
character is or is not something with a zero value.
What has that to do with what he said? Here, you are not disagreeing with
something he said, but with something he did not say.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 9 '08 #46
On Mon, 08 Sep 2008 10:54:02 +0000, Sjoerd <sj******@gmail.comwrote:
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
> char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
While you correctly identified the statements as initialisation, I
suspect you are confusing initialisation with assignment.

Note that the RHS is {0}, not 0.

Finally, if an array is defined as "int a[ARRSIZE];", then "a[ARRSIZE]"
is NOT an element of the array 'a'.

- Anand

Sep 9 '08 #47
On Mon, 08 Sep 2008 17:48:20 +0000, Richard Heathfield wrote:

I don't think it would be reasonable to call it plagiarism, since it's
blindingly obvious to all concerned that it's basically the K&R2 code.
No, it is not. That I learned from Stroustrup, section 6.2.5, special
edition. I do not even remember that I ever saw that code ever in K&R2.


--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is Blocked. Reason: Excessive Spamming

Sep 9 '08 #48
On Mon, 08 Sep 2008 17:48:20 +0000, Richard Heathfield wrote:

It isn't very good camouflage, though, since any experienced C
programmer will recognise it for what it is. It's just a more elegant
way to write the code. We don't write char foo[8] = { 'H', 'e', 'l',
'l', 'o', '\0', '\0', '\0' } just because it makes explicit the fact
that eight characters are being copied into the array. We write char
foo[8] = "Hello", and trust that competent programmers will understand.

[snip]

That whole discussion leaves me wondering whether:

char arrc[100] = {0};

is same as:

char arrc[100];
memset(arrc, '\0', 100);

or whether latter is more expansive than former ? and which one is
advised to use by c.l.c ?

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is Blocked. Reason: Excessive Spamming

Sep 9 '08 #49
On Mon, 08 Sep 2008 19:08:08 +0200, Richard wrote:
>Nate Eldredge <na**@vulcan.lanwrites:
It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code. I suspect if you put 100 C programmers
in clean rooms and asked them to write an implementation of strcpy,
you'd only get about three essentially different versions, and this is
one of them. K&R is probably the most memorable appearance of the
`*p++ = *q++' idiom, but just because one saw it there and continues
to use it doesn't make one a plagiarist. It's a textbook, after all.
You would be amazed at how few would actually do it this way. There are
many people out there who discourage such stuff. I even read here once
that it "misuses C" ... the mind boggles. I have seen many code bases
where you hardly ever see a pointer used in its natural habitat. A
crying shame IMO.

I am not a native English man so I don't know what you mean by "....used
in its natural habitat..."

Do you want to say that c.l.c discourages *p++ = *q++ ?


--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is Blocked. Reason: Excessive Spamming

Sep 9 '08 #50

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by A_StClaire_ | last post: by
44 posts views Thread by Nicolas | last post: by
1 post views Thread by Josh Wilson | last post: by
302 posts views Thread by Lee | last post: by
38 posts views Thread by edu.mvk | last post: by
16 posts views Thread by mdh | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.