public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* memcpy(p,p,len)
@ 2010-04-30 14:10 Joakim Tjernlund
  2010-04-30 14:13 ` memcpy(p,p,len) Jan-Benedict Glaw
  0 siblings, 1 reply; 9+ messages in thread
From: Joakim Tjernlund @ 2010-04-30 14:10 UTC (permalink / raw)
  To: gcc


Is memcpy supposed to work when the src and dest are the same:
memcpy(p, p, 100);

    Jocke

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 14:10 memcpy(p,p,len) Joakim Tjernlund
@ 2010-04-30 14:13 ` Jan-Benedict Glaw
  2010-04-30 14:19   ` memcpy(p,p,len) Joakim Tjernlund
  0 siblings, 1 reply; 9+ messages in thread
From: Jan-Benedict Glaw @ 2010-04-30 14:13 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 501 bytes --]

On Fri, 2010-04-30 16:08:15 +0200, Joakim Tjernlund <joakim.tjernlund@transmode.se> wrote:
> Is memcpy supposed to work when the src and dest are the same:
> memcpy(p, p, 100);

It may work, but you cannot rely on it. Use memmove() alternatively.

MfG, JBG

-- 
      Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
Signature of:              Alles sollte so einfach wie möglich gemacht sein.
the second  :                          Aber nicht einfacher.  (Einstein)

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 14:13 ` memcpy(p,p,len) Jan-Benedict Glaw
@ 2010-04-30 14:19   ` Joakim Tjernlund
  2010-04-30 14:30     ` memcpy(p,p,len) Jan-Benedict Glaw
  2010-04-30 14:37     ` memcpy(p,p,len) Paul Koning
  0 siblings, 2 replies; 9+ messages in thread
From: Joakim Tjernlund @ 2010-04-30 14:19 UTC (permalink / raw)
  To: Jan-Benedict Glaw; +Cc: gcc

Jan-Benedict Glaw <jbglaw@lug-owl.de> wrote on 2010/04/30 16:10:42:
>
> On Fri, 2010-04-30 16:08:15 +0200, Joakim Tjernlund
> <joakim.tjernlund@transmode.se> wrote:
> > Is memcpy supposed to work when the src and dest are the same:
> > memcpy(p, p, 100);
>
> It may work, but you cannot rely on it. Use memmove() alternatively.

My view too, but gcc 3.4.6 on gcc does this:
struct my_struct {
	long a100[100];
};
static inline
func(struct my_struct *h1, struct my_struct *h2)
{
	*h1 = *h2;
}
mytest(struct my_struct *my_h1)
{
	func(my_h1, my_h1);
}

-------------
	.file	"tst.c"
	.section	".text"
	.align 2
	.globl mytest
	.type	mytest, @function
mytest:
	mflr 0
	stwu 1,-16(1)
	mr 4,3
	li 5,400
	stw 0,20(1)
	bl memcpy
	lwz 0,20(1)
	addi 1,1,16
	mtlr 0
	blr
	.size	mytest, .-mytest
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.9)"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 14:19   ` memcpy(p,p,len) Joakim Tjernlund
@ 2010-04-30 14:30     ` Jan-Benedict Glaw
  2010-04-30 14:32       ` memcpy(p,p,len) Mark Mielke
  2010-04-30 14:37     ` memcpy(p,p,len) Paul Koning
  1 sibling, 1 reply; 9+ messages in thread
From: Jan-Benedict Glaw @ 2010-04-30 14:30 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 807 bytes --]

On Fri, 2010-04-30 16:14:36 +0200, Joakim Tjernlund <joakim.tjernlund@transmode.se> wrote:
> Jan-Benedict Glaw <jbglaw@lug-owl.de> wrote on 2010/04/30 16:10:42:
> > On Fri, 2010-04-30 16:08:15 +0200, Joakim Tjernlund
> > <joakim.tjernlund@transmode.se> wrote:
> > > Is memcpy supposed to work when the src and dest are the same:
> > > memcpy(p, p, 100);
> >
> > It may work, but you cannot rely on it. Use memmove() alternatively.
> 
> My view too, but gcc 3.4.6 on gcc does this:
[...]

Surely, it may/will work here and there. But it's not portable :)  And
I won't rely on a "it worked once" fact.

MfG, JBG

-- 
      Jan-Benedict Glaw      jbglaw@lug-owl.de              +49-172-7608481
Signature of:          GDB has a 'break' feature; why doesn't it have 'fix' too?
the second  :

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 14:30     ` memcpy(p,p,len) Jan-Benedict Glaw
@ 2010-04-30 14:32       ` Mark Mielke
  2010-04-30 15:14         ` memcpy(p,p,len) Joe Buck
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Mielke @ 2010-04-30 14:32 UTC (permalink / raw)
  To: Jan-Benedict Glaw; +Cc: Joakim Tjernlund, gcc

Just a quick comment than Jan-Benedict's opinion is widely shared by the 
specification and by the Linux glibc manpage:

DESCRIPTION
        The  memcpy()  function  copies  n bytes from memory area src to 
memory
        area dest.  The memory areas should not overlap.  Use memmove(3) 
if the
        memory areas do overlap.

It doesn't matter if it sometimes works. Sometimes works programs are 
sometimes doesn't work programs. :-)

Cheers,
mark

On 04/30/2010 10:25 AM, Jan-Benedict Glaw wrote:
> On Fri, 2010-04-30 16:14:36 +0200, Joakim Tjernlund<joakim.tjernlund@transmode.se>  wrote:
>    
>> Jan-Benedict Glaw<jbglaw@lug-owl.de>  wrote on 2010/04/30 16:10:42:
>>      
>>> On Fri, 2010-04-30 16:08:15 +0200, Joakim Tjernlund
>>> <joakim.tjernlund@transmode.se>  wrote:
>>>        
>>>> Is memcpy supposed to work when the src and dest are the same:
>>>> memcpy(p, p, 100);
>>>>          
>>> It may work, but you cannot rely on it. Use memmove() alternatively.
>>>        
>> My view too, but gcc 3.4.6 on gcc does this:
>>      
> [...]
>
> Surely, it may/will work here and there. But it's not portable :)  And
> I won't rely on a "it worked once" fact.
>
> MfG, JBG
>
>    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: memcpy(p,p,len)
  2010-04-30 14:19   ` memcpy(p,p,len) Joakim Tjernlund
  2010-04-30 14:30     ` memcpy(p,p,len) Jan-Benedict Glaw
@ 2010-04-30 14:37     ` Paul Koning
  1 sibling, 0 replies; 9+ messages in thread
From: Paul Koning @ 2010-04-30 14:37 UTC (permalink / raw)
  To: Joakim Tjernlund, Jan-Benedict Glaw; +Cc: gcc

That would be a bug.

If h1 and h2 were marked __restrict__ then using memcpy to make the
assignment is valid, but without that marking h1 may be == h2 so memmove
is required.

	paul

> -----Original Message-----
> From: Joakim Tjernlund [mailto:joakim.tjernlund@transmode.se]
> Sent: Friday, April 30, 2010 10:15 AM
> To: Jan-Benedict Glaw
> Cc: gcc@gcc.gnu.org
> Subject: Re: memcpy(p,p,len)
> 
> Jan-Benedict Glaw <jbglaw@lug-owl.de> wrote on 2010/04/30 16:10:42:
> >
> > On Fri, 2010-04-30 16:08:15 +0200, Joakim Tjernlund
> > <joakim.tjernlund@transmode.se> wrote:
> > > Is memcpy supposed to work when the src and dest are the same:
> > > memcpy(p, p, 100);
> >
> > It may work, but you cannot rely on it. Use memmove() alternatively.
> 
> My view too, but gcc 3.4.6 on gcc does this:
> struct my_struct {
> 	long a100[100];
> };
> static inline
> func(struct my_struct *h1, struct my_struct *h2)
> {
> 	*h1 = *h2;
> }
> mytest(struct my_struct *my_h1)
> {
> 	func(my_h1, my_h1);
> }
> 
> -------------
> 	.file	"tst.c"
> 	.section	".text"
> 	.align 2
> 	.globl mytest
> 	.type	mytest, @function
> mytest:
> 	mflr 0
> 	stwu 1,-16(1)
> 	mr 4,3
> 	li 5,400
> 	stw 0,20(1)
> 	bl memcpy
> 	lwz 0,20(1)
> 	addi 1,1,16
> 	mtlr 0
> 	blr
> 	.size	mytest, .-mytest
> 	.section	.note.GNU-stack,"",@progbits
> 	.ident	"GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0,
> pie-8.7.9)"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 14:32       ` memcpy(p,p,len) Mark Mielke
@ 2010-04-30 15:14         ` Joe Buck
  2010-04-30 15:52           ` memcpy(p,p,len) Richard Guenther
  0 siblings, 1 reply; 9+ messages in thread
From: Joe Buck @ 2010-04-30 15:14 UTC (permalink / raw)
  To: Mark Mielke; +Cc: Jan-Benedict Glaw, Joakim Tjernlund, gcc

On Fri, Apr 30, 2010 at 07:30:33AM -0700, Mark Mielke wrote:
> Just a quick comment than Jan-Benedict's opinion is widely shared by the 
> specification and by the Linux glibc manpage:
> 
> DESCRIPTION
>         The  memcpy()  function  copies  n bytes from memory area src to 
> memory
>         area dest.  The memory areas should not overlap.  Use memmove(3) 
> if the
>         memory areas do overlap.
> 
> It doesn't matter if it sometimes works. Sometimes works programs are 
> sometimes doesn't work programs. :-)

The typical memcpy function will fail for overlapping but unequal memory
ranges, but will work for src == dst.  Switching to memmove would degrade
performance, and that should only be done if there is an actual, rather
than a theoretical bug.  Note that for this use, it's not possible (if
the program is valid) for the ranges to overlap but be unequal.

Another alternative is that instead of using memcpy, a specialized
function could be used that has the required property (the glibc
memcpy does).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 15:14         ` memcpy(p,p,len) Joe Buck
@ 2010-04-30 15:52           ` Richard Guenther
  2010-05-01  0:07             ` memcpy(p,p,len) Joe Buck
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Guenther @ 2010-04-30 15:52 UTC (permalink / raw)
  To: Joe Buck; +Cc: Mark Mielke, Jan-Benedict Glaw, Joakim Tjernlund, gcc

On Fri, Apr 30, 2010 at 5:05 PM, Joe Buck <Joe.Buck@synopsys.com> wrote:
> On Fri, Apr 30, 2010 at 07:30:33AM -0700, Mark Mielke wrote:
>> Just a quick comment than Jan-Benedict's opinion is widely shared by the
>> specification and by the Linux glibc manpage:
>>
>> DESCRIPTION
>>         The  memcpy()  function  copies  n bytes from memory area src to
>> memory
>>         area dest.  The memory areas should not overlap.  Use memmove(3)
>> if the
>>         memory areas do overlap.
>>
>> It doesn't matter if it sometimes works. Sometimes works programs are
>> sometimes doesn't work programs. :-)
>
> The typical memcpy function will fail for overlapping but unequal memory
> ranges, but will work for src == dst.  Switching to memmove would degrade
> performance, and that should only be done if there is an actual, rather
> than a theoretical bug.  Note that for this use, it's not possible (if
> the program is valid) for the ranges to overlap but be unequal.
>
> Another alternative is that instead of using memcpy, a specialized
> function could be used that has the required property (the glibc
> memcpy does).

Note that language semantics come in here as well.  The middle-end
assumes that when an assignment is not BLKmode that the RHS
will be read before the lhs will be written.  It does not assume so
otherwise and the behavior is undefined for overlapping *p and *q
if you do *p = *q.  Thus it is up to the frontend to emit a call to
memmove in this case (the C++ frontend got bitten by this and
was fixed).

Richard.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: memcpy(p,p,len)
  2010-04-30 15:52           ` memcpy(p,p,len) Richard Guenther
@ 2010-05-01  0:07             ` Joe Buck
  0 siblings, 0 replies; 9+ messages in thread
From: Joe Buck @ 2010-05-01  0:07 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Mark Mielke, Jan-Benedict Glaw, Joakim Tjernlund, gcc

On Fri, Apr 30, 2010 at 08:29:19AM -0700, Richard Guenther wrote:
> On Fri, Apr 30, 2010 at 5:05 PM, Joe Buck <Joe.Buck@synopsys.com> wrote:
> > On Fri, Apr 30, 2010 at 07:30:33AM -0700, Mark Mielke wrote:
> >> Just a quick comment than Jan-Benedict's opinion is widely shared by the
> >> specification and by the Linux glibc manpage:
> >>
> >> DESCRIPTION
> >>         The  memcpy()  function  copies  n bytes from memory area src to
> >> memory
> >>         area dest.  The memory areas should not overlap.  Use memmove(3)
> >> if the
> >>         memory areas do overlap.
> >>
> >> It doesn't matter if it sometimes works. Sometimes works programs are
> >> sometimes doesn't work programs. :-)
> >
> > The typical memcpy function will fail for overlapping but unequal memory
> > ranges, but will work for src == dst.  Switching to memmove would degrade
> > performance, and that should only be done if there is an actual, rather
> > than a theoretical bug.  Note that for this use, it's not possible (if
> > the program is valid) for the ranges to overlap but be unequal.
> >
> > Another alternative is that instead of using memcpy, a specialized
> > function could be used that has the required property (the glibc
> > memcpy does).
> 
> Note that language semantics come in here as well.  The middle-end
> assumes that when an assignment is not BLKmode that the RHS
> will be read before the lhs will be written.  It does not assume so
> otherwise and the behavior is undefined for overlapping *p and *q
> if you do *p = *q.  Thus it is up to the frontend to emit a call to
> memmove in this case (the C++ frontend got bitten by this and
> was fixed).

If the only possibilities are that p == q, or *p and *q do not overlap,
then
  if (p != q)
     memcpy(p, q, n);
would be cheaper than memmove, which has to choose between forward and
backward copying to handle overlap.  However, some memcpy implementations
(including the one in glibc) will do the right thing even without the
test.

If structure copying suddenly produces memmove calls, that would not
be good.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-05-01  0:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-30 14:10 memcpy(p,p,len) Joakim Tjernlund
2010-04-30 14:13 ` memcpy(p,p,len) Jan-Benedict Glaw
2010-04-30 14:19   ` memcpy(p,p,len) Joakim Tjernlund
2010-04-30 14:30     ` memcpy(p,p,len) Jan-Benedict Glaw
2010-04-30 14:32       ` memcpy(p,p,len) Mark Mielke
2010-04-30 15:14         ` memcpy(p,p,len) Joe Buck
2010-04-30 15:52           ` memcpy(p,p,len) Richard Guenther
2010-05-01  0:07             ` memcpy(p,p,len) Joe Buck
2010-04-30 14:37     ` memcpy(p,p,len) Paul Koning

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).