Implementing my own memcpy

C

CBFalconer

Netocrat said:
.... snip ...

And indeed checking this shows that gcc still doesn't complain
about incrementing a void pointer.

Showing that you are using gcc incorrectly. Use -W -Wall -ansi
-pedantic. You can replace -ansi with -std=C99 if you wish and
your library can handle it.
 
P

pete

Chris Torek wrote:
if (n)
do
*dst++ = *src++;
while (--n != 0);
return dst0;
}

(you can also write the loop as "while (n--) *dst++ = *src++" but I
find the above easier to read and think about).

To me,
while (n-- != 0) {}
is very easy to read as a loop that's going to iterate
as many times as what the initial value of n is.
 
N

Netocrat

Showing that you are using gcc incorrectly. Use -W -Wall -ansi
-pedantic.
You can replace -ansi with -std=C99 if you wish and your library can
handle it.

The word complain was a poor choice, and if you had read it in context
you would have understood that and wouldn't have to pick nits with my
phrasing.

I said that my assumption had been that trying to increment a void
pointer "would not work at all", not that it would generate a "complaint",
and that that assumption is what caused me to falsely believe that the
cast had modified the pointer arithmetic.

So the sentence you quote was added to confirm that my assumption was
wrong: that gcc does still "work" ie compile without error given code that
increments a void pointer; not that it doesn't generate warnings.
Granted, I didn't use the options in this case but that's beside the point
I was trying to make.

I am aware of those options and usually do use them (apart from the -W
option which now that I read about it looks useful, so I'll add it in
future).

Look, I understand the importance of correctness and precision especially
in a group about a standardised programming language, but if you're going
to jump on what you see as an error in someone's phrasing - and even to go
further and make assumptions about their general use of the compiler - at
least give them the benefit of the doubt and try to see if what they're
saying can be interpreted correctly given the overall context.
 
L

Lefty Bigfoot

How widely and fully implemented is the later standard C99 versus the
earlier C90 standard?

Don't write anything that uses C99 extensions unless you don't
care about portability this century.
 
S

Stan Milam

Netocrat said:
The word complain was a poor choice, and if you had read it in context
you would have understood that and wouldn't have to pick nits with my
phrasing.

I said that my assumption had been that trying to increment a void
pointer "would not work at all", not that it would generate a "complaint",
and that that assumption is what caused me to falsely believe that the
cast had modified the pointer arithmetic.

So the sentence you quote was added to confirm that my assumption was
wrong: that gcc does still "work" ie compile without error given code that
increments a void pointer; not that it doesn't generate warnings.
Granted, I didn't use the options in this case but that's beside the point
I was trying to make.

I am aware of those options and usually do use them (apart from the -W
option which now that I read about it looks useful, so I'll add it in
future).

Look, I understand the importance of correctness and precision especially
in a group about a standardised programming language, but if you're going
to jump on what you see as an error in someone's phrasing - and even to go
further and make assumptions about their general use of the compiler - at
least give them the benefit of the doubt and try to see if what they're
saying can be interpreted correctly given the overall context.

Yes! Amen!

Stan.
 
C

Chris Torek

How widely and fully implemented is the later standard C99 versus the
earlier C90 standard?

"Not very". The situation is improving (inasmuch as C99 is an
"improvement" anyway :) ), but slowly. A few years ago there were
no compilers that claimed even to attempt C99 support; now I think
there are two or three.
 
R

Richard Harter

I prefer the conciseness of the second, but I prefer even more testing
against a maximum pointer.

You shouldn't. IMNSHO one should be equally comfortable with testing
against a minimum as with testing against a maximum, just as in
mathematics one should be comfortable both with proof by induction and
proof by infinite descent, and in programming with both recursion and
iteration. Not being comfortable with both directions limits you.



Richard Harter, (e-mail address removed)
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
 
R

Richard Harter

To me,
while (n-- != 0) {}
is very easy to read as a loop that's going to iterate
as many times as what the initial value of n is.

Indeed. A disadvantage, though, is that n does not correspond to
array indices. An alternate formulation is

for (; --n >= 0;) {}

This can be useful if one wants to work, so to speak, from the high
end to the low end of an array. In a copy routine one wants to be
able to work either way depending on overlaps. Thus if the layout
looks like this

SSSSS.....
DDDDD.....

one wants to work from the high end down whereas if it looks like

DDDDD.....
SSSSS.....

one wants to work from low end up. Thus (in a flat memory model) we
might say something like

if (src <dest) for ( ;--n >= 0 ; ) dst[n] = src[n];
else for (i=0; --n>= 0 ; i++) dst = src;

provided that we wanted to use array indexing rather than pointers.


Richard Harter, (e-mail address removed)
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
 
M

Michael Mair

Richard said:
Indeed. A disadvantage, though, is that n does not correspond to
array indices. An alternate formulation is

for (; --n >= 0;) {}

You just got yourself an infinite loop for n of unsigned integer
type -- which incidentally is the case (look upthread: size_t n).
If you insist on this form, use
for (; --n != (size_t)-1;) {}
instead. Even in situations where the cast is not necessary, I
would leave it there for clarity and as ward against
"optimisations".

[snip]

Cheers
Michael
 
C

CBFalconer

Netocrat said:
How widely and fully implemented is the later standard C99 versus
the earlier C90 standard?

The following accesses a draft that include further modifications,
but has the disadvantage of being a .pdf file rather than a .txt
file. This hampers quick and easy searches, grepping, quoting,
etc.

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf>

Meanwhile, I think I have a suitably formatted and organized
version of n869.txt mounted as:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>

which means you have to have bzip2 on your system to extract it
properly, but minimizes the download time (it is about 200k).
 
C

CBFalconer

Netocrat said:
The word complain was a poor choice, and if you had read it in
context you would have understood that and wouldn't have to pick
nits with my phrasing.

I said that my assumption had been that trying to increment a void
pointer "would not work at all", not that it would generate a
"complaint", and that that assumption is what caused me to falsely
believe that the cast had modified the pointer arithmetic.

The point is not so much what you understand, but what other
readers of your article will understand. My post was intended to
correct the mistaken impression that gcc fails to properly diagnose
misuse of a void *.
 
P

pete

Richard said:
Indeed. A disadvantage, though, is that n does not correspond to
array indices. An alternate formulation is

for (; --n >= 0;) {}

This can be useful if one wants to work, so to speak, from the high
end to the low end of an array.

No. Like Michael Mair said, you infinite looped.

(n-- != 0) is exactly perfect for work
from the high end to the low end of an array.

void *mem_cpy(void *s1, const void *s2, size_t n)
{
unsigned char *p1 = s1;
const unsigned char *p2 = s2;

while (n-- != 0) {
p1[n] = p2[n];
}
return s1;
}
 
C

CBFalconer

Michael said:
Richard Harter wrote:
.... snip ...

You just got yourself an infinite loop for n of unsigned integer
type -- which incidentally is the case (look upthread: size_t n).
If you insist on this form, use
for (; --n != (size_t)-1;) {}
instead. Even in situations where the cast is not necessary, I
would leave it there for clarity and as ward against
"optimisations".

For something like that use a while loop, no need for the other for
clauses. However the for can combine initialization, and allows:

for (n = SIZE; n--; /* maybe something else */ ) {}

and is proof against unsignedness, yet n within the loop is a
direct array index. However I would normally use a while loop
anyhow.
 
R

Richard Harter

Richard Harter wrote:
You just got yourself an infinite loop for n of unsigned integer
type -- which incidentally is the case (look upthread: size_t n).
If you insist on this form, use
for (; --n != (size_t)-1;) {}
instead. Even in situations where the cast is not necessary, I
would leave it there for clarity and as ward against
"optimisations".

My apologies. I thought it obvious that the form I mentioned required
signed integers. I didn't think it necessary to mention the caveat
but I was in error.




Richard Harter, (e-mail address removed)
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
 
R

Richard Harter

No. Like Michael Mair said, you infinite looped.

Well, no, I didn't. See reply to Michael.
(n-- != 0) is exactly perfect for work
from the high end to the low end of an array.

void *mem_cpy(void *s1, const void *s2, size_t n)
{
unsigned char *p1 = s1;
const unsigned char *p2 = s2;

while (n-- != 0) {
p1[n] = p2[n];
}
return s1;
}

Point taken. That form is safe (and best) for unsigned integers.
However it is unsafe for signed integers; if for any reason n is
negative it blows up.


Richard Harter, (e-mail address removed)
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
 
P

pete

Richard said:
Well, no, I didn't. See reply to Michael.

If you're thinking that n could be negative,
then it's simpler to write the code so that there
are no values of n which cause undefined behavior.

while ( n > 0) {--n;}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,166
Messages
2,570,903
Members
47,444
Latest member
Michaeltoyler01

Latest Threads

Top