linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Question on memcpy()
  2004-09-15  8:33 RedHat Itanium 64 GCC 3.2.3 linking problems sheetal fegde
@ 2004-09-15 11:17 ` Wen Guangcheng
  0 siblings, 0 replies; 3+ messages in thread
From: Wen Guangcheng @ 2004-09-15 11:17 UTC (permalink / raw)
  To: linux-c-programming

Hello Gurus,

I am trying to fix a bug in a  code. I found something like this,

struct sample A, B;
...
...
memset(&A, 0, sizeof(sample));
memcpy(&A, (char *)&B, sizeof(sample));
...
I could not understand why the second argument is (char *)&B, but not &B.
I think it should be &B. 

Sometimes I found A is all zero. but B is not all zero in fact.  
Is it due to the second argument (char *)&B?

Any comment is appreciated and thanks in advance.

Best regards,

--Wen


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

* RE: Question on memcpy()
@ 2004-09-15 14:14 Huber, George K RDECOM CERDEC STCD SRI
  2004-09-15 14:34 ` Charlie Gordon
  0 siblings, 1 reply; 3+ messages in thread
From: Huber, George K RDECOM CERDEC STCD SRI @ 2004-09-15 14:14 UTC (permalink / raw)
  To: linux-c-programming

Wen wrote,

>struct sample A, B;
>...
>...
>memset(&A, 0, sizeof(sample));
>memcpy(&A, (char *)&B, sizeof(sample));
>...
>I could not understand why the second argument is (char *)&B, but not &B.
>I think it should be &B. 

I would have to agree with you that the second argument should be just &B.
If 
you were going to cast it to anything, I would cast it to const void*.  I
recall 
that any pointer type may be promoted to a void-pointer by the compiler,
although
my memory is a littel fuzzy on this.  

>Sometimes I found A is all zero. but B is not all zero in fact.  
>Is it due to the second argument (char *)&B?

I would be more suspect of the third argument, I beleive that the argument
to
sizeof should be `struct sample' not just `sample' (I am not sure how the
compiler
will interpret the type sample).  I would code the above two lines in one of
the 
following ways,

method (1):
memset((void*)&A, 0, sizeof(struct sample))
memcpy((void*)&A, (const void*)&B, sizeof(struct sample))

method (2):
memset((void*)&A, 0, sizeof(A))
memcpy((void*)&A, (const void*)&B, sizeof(B))

Note: the explicit cast are probably unnecessary, I do them for two reasons.
First,
      I think it improves the readability of the as it is clearly apparent
what type
      of casts are going one.  Secondly, I always run my source code though
severl 
      `lint' checkers and one will always throw a warning about a conversion
of 
      pointer to sometime to void*.  Doing the explicit casts will cause the
warning 
      to be suspressed.

George.

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

* Re: Question on memcpy()
  2004-09-15 14:14 Question on memcpy() Huber, George K RDECOM CERDEC STCD SRI
@ 2004-09-15 14:34 ` Charlie Gordon
  0 siblings, 0 replies; 3+ messages in thread
From: Charlie Gordon @ 2004-09-15 14:34 UTC (permalink / raw)
  To: linux-c-programming

"Huber, George K RDECOM CERDEC STCD SRI" <George.K.Huber@us.army.mil> wrote
in message
news:E3E30069B061524E90BCEE4417E3066113852B@monm207.monmouth.army.mil...
> Wen wrote,
>
> >struct sample A, B;
> >...
> >...
> >memset(&A, 0, sizeof(sample));
> >memcpy(&A, (char *)&B, sizeof(sample));
> >...
> >I could not understand why the second argument is (char *)&B, but not &B.
> >I think it should be &B.
>

This is correct, I suspect this cast comes from the programmer ancient
belief that memcpy should be passed char pointers (confusingly refered to as
byte pointers).  Since it is defined to take (void *, const void*, size_t) ,
passing it any type of pointer is fine, including superfluous casts.

It should be noted that while the initialization to 0 required a call to
memset, copying the raw contents of une struct to another can be done more
efficiently (usually) in C by writing:

A = B;

as far as why sizeof(sample) is accepted at all by the compiler, there 3
possible explanations:

- there is a typedef for sample, at it better be defined to struct sample.
- there is a variable by the name sample in scope, and it better be an
instance of struct sample.
- there is a #define defining the identifier sample to something valid as an
operand to sizeof.  Again, it better be consistent with the use in these 2
lines.

It would be better to make no assumptions about the types of A and B and
write:

memset(&A, 0, sizeof(A));
...
A = B;

This way, the compiler will protest if A and B types don't match, and will
compute the right size for A no matter what type it's defined to be.

Chqrlie.




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

end of thread, other threads:[~2004-09-15 14:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-15 14:14 Question on memcpy() Huber, George K RDECOM CERDEC STCD SRI
2004-09-15 14:34 ` Charlie Gordon
  -- strict thread matches above, loose matches on Subject: below --
2004-09-15  8:33 RedHat Itanium 64 GCC 3.2.3 linking problems sheetal fegde
2004-09-15 11:17 ` Question on memcpy() Wen Guangcheng

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 NNTP newsgroup(s).