bitwise copying here?

W

webfan

In the code below, will the assignment z= y do bitwise copying?

struct x
{
int a;
int b;
int c;
};

main()
{
struct x z, y;
...
z = y;

}
 
M

Michael Mair

webfan said:
In the code below, will the assignment z= y do bitwise copying?

struct x
{
int a;
int b;
int c;
};

main()
{
struct x z, y;
...
z = y;

}

Probably, but not guaranteedly.
What is guaranteed is that you have the effect of
z.a = y.a;
z.b = y.b;
z.c = y.c;

If there are two possible representations for one of these values,
then the assignment may change the representation.

If, for some strange reason, struct x has padding bytes, then
the representation of a, b, and c may be the same while the
representation of the padding bytes is different.

If you want a bit-by-bit copy, use
memcpy(&z, &y, sizeof z);


Cheers
Michael
 
E

Eric Sosman

kondal said:
Michael Mair wrote:



memcpy does a byte-by-byte copy not bit-by-bit

memcpy() may do a byte-by-byte copy, or bit-by-bit, or
nybble-by-nybble, or something else. The Standard says only
that it "copies n characters," but says nothing about how
those characters are to be copied. As a practical matter,
this allows a memcpy() implementation to copy four-byte words
or eight-byte octawords or other larger-than-byte-sized units,
if it can profitably do so.

From the point of view of a strictly conforming program,
the difference (if there is one) is subtle to the point of
being undetectably invisible.
 
J

jmcgill

kondal said:
memcpy does a byte-by-byte copy not bit-by-bit

There's no guarantee that it's done byte-by-byte.
If your underlying architecture has a block copy,
a memcpy implementation would be allowed to use it.

The motivation for mem* library routines is to allow
functions that have greater efficiency than straightforward
array copying.

There are common architectures that provide fast block-copy
instructions, and it would be a shame if a C library didn't
take advantage of them.
 
Z

zhengda

Michael said:
Probably, but not guaranteedly.
What is guaranteed is that you have the effect of
z.a = y.a;
z.b = y.b;
z.c = y.c;

If there are two possible representations for one of these values,
then the assignment may change the representation.

If, for some strange reason, struct x has padding bytes, then
the representation of a, b, and c may be the same while the
representation of the padding bytes is different.
I don't understand it well. Can you take an example?
Thank you
 
M

Michael Mair

kondal said:
memcpy does a byte-by-byte copy not bit-by-bit

So what? Note that I took up the OP's wording.
unsigned char has no padding bits, so the representation of
y is copied to z. Of course, we only stop the copying at byte
borders -- but the result does not differ from bitwise copying.

Cheers
Michael
 
M

Michael Mair

zhengda said:
I don't understand it well. Can you take an example?

Example padding bytes:
Say, sizeof int == 2, CHAR_BIT == 8 (i.e., we have 16 bit ints)
and access to 8 byte storage regions is somehow "more efficient"
than three times 2 bytes. Then, struct x might have the following
layout:
first two bytes -- a
second two bytes -- b
third two bytes -- c
last two bytes -- padding
i.e. sizeof (struct x) == 8 instead of the minimal possible 6.
Writing z = y does not say what happens to the padding -- it might
be copied over or not.

Example different representations[*]:
Say, we have one's complement. This gives us an all bits zero
representation of 0 and and all bits one representation for 0,
a "negative zero". If the implementation wants to eliminate
occurrences of negative zero, it could do so at copying, i.e.
y.a is all bits one and z.a becomes all bits zero but z.a == y.a.


Cheers
Michael

[*] It is possible that I misunderstood what the implementation
may and may not do with negative zeros. In that case, we can consider
padding bits that are not copied over.
I thought the negative zero example more interesting.
 
Z

zhengda

Michael said:
zhengda said:
I don't understand it well. Can you take an example?


Example padding bytes:
Say, sizeof int == 2, CHAR_BIT == 8 (i.e., we have 16 bit ints)
and access to 8 byte storage regions is somehow "more efficient"
than three times 2 bytes. Then, struct x might have the following
layout:
first two bytes -- a
second two bytes -- b
third two bytes -- c
last two bytes -- padding
i.e. sizeof (struct x) == 8 instead of the minimal possible 6.
Writing z = y does not say what happens to the padding -- it might
be copied over or not.

Example different representations[*]:
Say, we have one's complement. This gives us an all bits zero
representation of 0 and and all bits one representation for 0,
a "negative zero". If the implementation wants to eliminate
I think the complement of -1 is the one whose bits are all 1.
occurrences of negative zero, it could do so at copying, i.e.
y.a is all bits one and z.a becomes all bits zero but z.a == y.a.


Cheers
Michael

[*] It is possible that I misunderstood what the implementation
may and may not do with negative zeros. In that case, we can consider
padding bits that are not copied over.
I thought the negative zero example more interesting.
 
M

Michael Mair

zhengda said:
Michael said:
zhengda wrote:
Example different representations[*]:
Say, we have one's complement. This gives us an all bits zero
representation of 0 and and all bits one representation for 0,
a "negative zero". If the implementation wants to eliminate

I think the complement of -1 is the one whose bits are all 1.

One's complement is a system for binary representation of numbers.
It is different from two's complement (which you are talking about).
In one's complement, -number == ~number.

Have a look at
http://en.wikipedia.org/wiki/Signed_number_representations
occurrences of negative zero, it could do so at copying, i.e.
y.a is all bits one and z.a becomes all bits zero but z.a == y.a.
[*] It is possible that I misunderstood what the implementation
may and may not do with negative zeros. In that case, we can consider
padding bits that are not copied over.
I thought the negative zero example more interesting.


Cheers
Michael
 
F

Frederick Gotham

webfan posted:
In the code below, will the assignment z= y do bitwise copying?

struct x
{
int a;
int b;
int c;
};

main()
{
struct x z, y;
...
z = y;

}


No, memberwise copy. The difference is that any padding between members is
not guaranteed to be replicated (maybe it's even guaranteed _not_ to be
replicated, but I'm not sure).

As others have stated, memcpy is useful for bitwise copy. Or perhaps the
following if you're fond of DIY:

struct MyStruct {
int a,b,c;
};

int main(void)
{
struct MyStruct y = {5,4,2},z;

char unsigned const *p = (char unsigned const*)&y;
char unsigned const *const pover = p+sizeof y;

char unsigned *q = (char unsigned*)&z;

do *q++ = *p++; while(p!=pover);

return 0;
}
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top