Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Memberwise copying?

6 views
Skip to first unread message

stork

unread,
Nov 23, 2009, 6:30:51 AM11/23/09
to
I had always thought that C++, if you did not make an explicit copy
constructor and assignment operator, copying would be bitwise, as if a
memcpy had been performed. But as I have been trying to learn boost,
particularly boost spirit, I see constructs that seem to me as if this
is not the case. Furthermore, although there are plenty of posts that
seem to uphold the bitwise copy theory, there are a few out there by
people that indicate that memberwise is the way.

So... I put it to the test and wrote the simple little short program,
at the end of this email, that does seem to be bear out, for gnu g++,
on Linux, that copying is memberwise. The output clearly shows that
the copying is memberwise as the assignment operators for the member
objects of my class are being called.

When did this change? Or did it change? Somehow I got the "bitwise"
thing beaten into my head way back in the day, maybe like the mid
1990s, that automatic copying was not memberwise. Maybe I've been
wrong all this time. Is this case? Is the copying of a class
memberwise? I think a lot of websites say that this is not the case,
and apparently wrongly so. Is is really more the case that even with
memberwise copy, arrays are pointers and only the pointers would be
copied, like a char * member would do the wrong thing come destructor
time, but its not actually bitwise, its just the nature of array
copying itself.

In the below example, I have a class zooto that I make a member of
another class called testo. I assign one testo to another and examine
the output. When one testo is assigned to another, I see two lines
indicating that the assignment operator had actually been called.

#include <iostream>
using namespace std;

class zooto {
int bytes[20];
int data;
public:

zooto()
{
data = 0;
for (int i = 0; i < sizeof(bytes); i++) {
bytes[ i ] = i;
data += i;
}
cout << "zooto " << this << " default constructed" << endl;
}

zooto( const zooto& obj ) : data( obj.data )
{
for (int i = 0; i < sizeof(bytes); i++)
bytes[ i ] = obj.bytes[ i ];
cout << "zooto " << this << " copy constructed" << endl;
}

zooto operator=(const zooto& obj) {
cout << "zooto assigned " << this << endl;
data = obj.data;
for (int i = 0; i < sizeof(bytes); i++)
bytes[ i ] = obj.bytes[ i ];
return *this;
}

virtual ~zooto() {
cout << "zooto " << this << " is being destroyed" << endl;
}

void runme() {
data *= 2;
}
};

struct testo {
zooto test1,
test2;

};

int test() {
testo test1, test2;

cout << "assignment!!!" << endl;
test1 = test2;

cout << "destruct!!!" << endl;
return 0;
}

int main() {
cout << "!!!Hello Worldxx!!!" << endl; // prints !!!Hello World!!!
test();
return 0;
}

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Peer S.

unread,
Nov 23, 2009, 4:43:04 PM11/23/09
to
On 23 Nov., 12:30, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.

It is memberwise, see 12.8.8 of the standard: "The implicitly-defined
copy constructor for class X performs a memberwise copy of its
subobjects. ...". Equivalent for the assignment operator, see 12.8.13.

Kind Regards,
Peer

Ulrich Eckhardt

unread,
Nov 23, 2009, 4:42:57 PM11/23/09
to
stork wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed.

Wrong. Copying is performed by invoking the copy constructor of each member.

> When did this change? Or did it change?

It didn't change in the last ten years. Note that in C, where there were no
copy constructors, memberwise copying was always the same as bytewise
copying.

> I think a lot of websites say that this is not the case, and apparently
> wrongly so.

Yes, there are lots of false information Out There.

> Is is really more the case that even with memberwise copy, arrays are
> pointers and only the pointers would be copied, like a char * member
> would do the wrong thing come destructor time, but its not actually
> bitwise, its just the nature of array copying itself.

Wait, compare these two structures:

struct a
{
char* s;
};
struct b
{
char s[10];
};

If you copy 'a', you will have a copy where the pointer points to the same
memory, which may be wrong. If you copy 'b', you will actually copy the
content. The contained array is really contained and not some kind of
pointer in disguise. Both copying operations are equivalent to a memcpy()
though.

> int bytes[20];


> for (int i = 0; i < sizeof(bytes); i++) {
> bytes[ i ] = i;

Danger: 'sizeof bytes' is actually the size in bytes, but bytes aren't
bytes. You want '(sizeof bytes)/(sizeof *bytes)' instead for the length of
the array.


Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

Bo Persson

unread,
Nov 23, 2009, 4:46:54 PM11/23/09
to
stork wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as
> if a memcpy had been performed. But as I have been trying to learn
> boost, particularly boost spirit, I see constructs that seem to me
> as if this is not the case. Furthermore, although there are plenty
> of posts that seem to uphold the bitwise copy theory, there are a
> few out there by people that indicate that memberwise is the way.
>
> So... I put it to the test and wrote the simple little short
> program, at the end of this email, that does seem to be bear out,
> for gnu g++, on Linux, that copying is memberwise. The output
> clearly shows that the copying is memberwise as the assignment
> operators for the member objects of my class are being called.
>
> When did this change? Or did it change?

It has never changed.

However, if the members are all PODs the optimizer might translate
this into a memcpy anyway. Assuming that is the best way to do a copy.


Bo Persson

Nick Hounsome

unread,
Nov 23, 2009, 4:45:42 PM11/23/09
to
On 23 Nov, 11:30, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.
>
> So... I put it to the test and wrote the simple little short program,
> at the end of this email, that does seem to be bear out, for gnu g++,
> on Linux, that copying is memberwise. The output clearly shows that
> the copying is memberwise as the assignment operators for the member
> objects of my class are being called.
>
> When did this change? Or did it change? Somehow I got the "bitwise"
> thing beaten into my head way back in the day, maybe like the mid
> 1990s, that automatic copying was not memberwise. Maybe I've been
> wrong all this time. Is this case? Is the copying of a class
> memberwise? I think a lot of websites say that this is not the case,
> and apparently wrongly so. Is is really more the case that even with
> memberwise copy, arrays are pointers and only the pointers would be
> copied, like a char * member would do the wrong thing come destructor
> time, but its not actually bitwise, its just the nature of array
> copying itself.

I suspect that "bitwise" was originally used to cover the behaviour of
unions which cannot logically be copied memberwise.

Michael Aaron Safyan

unread,
Nov 23, 2009, 4:47:14 PM11/23/09
to
On Nov 23, 5:30 am, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise...

The behavior you observed has always been the standard behavior. It
was probably explained as a memcpy, because when no assignment
operator is provided (and all the members similarly do not provide
assignment operators), then this member-wise assignment has the same
observed behavior as a memcpy.

peter koch larsen

unread,
Nov 23, 2009, 4:44:02 PM11/23/09
to
On 23 Nov., 12:30, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.
>
Standard C++ has always had memberwise copy.

[snip]


>
> When did this change? Or did it change? Somehow I got the "bitwise"
> thing beaten into my head way back in the day, maybe like the mid
> 1990s, that automatic copying was not memberwise.

You must have been one of the very first C++ users. I vaguely remember
Stroustrup writing that in some of the earliest C++ compilers, copy
was bitwise, but my guess is that this was changed in '95. But not on
your compiler, apparently.

[snip}

/Peter

Francis Glassborow

unread,
Nov 23, 2009, 4:42:24 PM11/23/09
to
stork wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.
>
I am at a loss to understand where you got the idea that copying would
default to bitwise (It is in C but then C does not have ctors so what
else could copying mean?. Nobody who has used C++ other than trivially
would expect anything other than memberwise copying. That is the only
way it has been over the two decades that I have been using C++.

Sheff

unread,
Nov 24, 2009, 12:28:43 AM11/24/09
to
On Nov 23, 2:30 pm, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.
>
> So... I put it to the test and wrote the simple little short program,
> at the end of this email, that does seem to be bear out, for gnu g++,
> on Linux, that copying is memberwise. The output clearly shows that
> the copying is memberwise as the assignment operators for the member
> objects of my class are being called.
that's correct, because "zooto operator=" is defined, so copying zooto
instances invokes this operator,
if you want pure bitwise copy of zooto data members just remove
"operator =" and make sure that all data members are POD.
in your case:

> int bytes[20];
> int data;
they are, so removing "operator =" will cause 'bytes' and 'data' to be
copied bitwise.

>
> When did this change? Or did it change?
nothing was changed

Andrey Tarasevich

unread,
Nov 24, 2009, 12:29:37 AM11/24/09
to
stork wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.

There has never been such thing as "bitwise" copying in C++ (or in C for
that matter). The copying has always been performed in memberwise fashion.

I also hear that strange term from time to time. I have no idea where it
comes from. Most likely, some poor quality book.

Even C language does not give you the guarantee that the physical result
of 'struct' assignment (since the moment 'struct' assignment was
allowed) is the same as the result of 'memcpy', since there's no
guarantee that the contents of the padding bytes gets copied by the
assignment operator.

Moreover, even when you assign the value of one 'int' object to another
'int' object there is no guarantee that the physical content of the
destination 'int' object is going to be the same as it would be in case
of 'memcpy', since the language does not guarantee that padding bits
(possibly present in an 'int' object) are copied by the assignment operator.

> When did this change? Or did it change?

It has never been "bitwise". So, it never changed.

--
Bets regards,
Andrey Tarasevich

Neil Butterworth

unread,
Nov 24, 2009, 12:35:56 AM11/24/09
to
Francis Glassborow wrote:
> I am at a loss to understand where you got the idea that copying would
> default to bitwise (It is in C but then C does not have ctors so what
> else could copying mean?. Nobody who has used C++ other than trivially
> would expect anything other than memberwise copying. That is the only
> way it has been over the two decades that I have been using C++.

To quote from The Design & Evolution of C++, section 11.4.4:

"Originally, assignment and initialisation were by default defined as
bitwise copy."

Unfortunately, Stroustrup doesn't say (at least in the quoted section)
when this changed to memberwise copy - I seem to remember it was at
Cfront 2.9, but I could easily be wrong.

Neil Butterworth

Daniel Krügler

unread,
Nov 24, 2009, 12:30:54 AM11/24/09
to
On 23 Nov., 12:30, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> memcpy had been performed. But as I have been trying to learn boost,
> particularly boost spirit, I see constructs that seem to me as if this
> is not the case. Furthermore, although there are plenty of posts that
> seem to uphold the bitwise copy theory, there are a few out there by
> people that indicate that memberwise is the way.
>
> So... I put it to the test and wrote the simple little short program,
> at the end of this email, that does seem to be bear out, for gnu g++,
> on Linux, that copying is memberwise. The output clearly shows that
> the copying is memberwise as the assignment operators for the member
> objects of my class are being called.
>
> When did this change? Or did it change? Somehow I got the "bitwise"
> thing beaten into my head way back in the day, maybe like the mid
> 1990s, that automatic copying was not memberwise. Maybe I've been
> wrong all this time. Is this case? Is the copying of a class
> memberwise?

Your assumptions as expressed literally are incorrect as long
as the original 1998 C++ standard has been published
(ISO/IEC 14882:1998(E)), but I don't know much about the pre-
standard era. The relevant quote here is 12.8 [class.copy]/8
for the copy c'tor:

"The implicitly defined copy constructor for class X performs a
memberwise copy of its subobjects. The order of copying is the
same as the order of initialization of bases and members in a
user-defined constructor (see 12.6.2). Each sub-object is copied
in the manner appropriate to its type:
� if the subobject is of class type, the copy constructor for
the class is used;
� if the subobject is an array, each element is copied, in the
manner appropriate to the element type;
� if the subobject is of scalar type, the builtin assignment
operator is used.
Virtual base class subobjects shall be copied only once by the
implicitly defined copy constructor (see 12.6.2)."

Note that it says "memberwise copy" and that bullet 1 specifically
requires the implementation to call the copy c'tor for class
types.

I believe you are confusing the difference between POD types and
non-POD types (In C++0x there will be a more refined category for
so-called "trivial" types). POD types may be copied by memcpy,
but there are also several requirements they need to satisfy,
among them they shall not have any user-defined c'tor, any
user-defined copy assignment operator, or any user-defined
destructor.

> I think a lot of websites say that this is not the case,
> and apparently wrongly so. Is is really more the case that even with
> memberwise copy, arrays are pointers and only the pointers would be
> copied, like a char * member would do the wrong thing come destructor
> time, but its not actually bitwise, its just the nature of array
> copying itself.

As above quote clearly says, even arrays need to be copied member-
wise.

> In the below example, I have a class zooto that I make a member of
> another class called testo. I assign one testo to another and examine
> the output. When one testo is assigned to another, I see two lines
> indicating that the assignment operator had actually been called.

Anything else would violate the standard.

> #include <iostream>
> using namespace std;
>
> class zooto {
> int bytes[20];
> int data;
> public:
>
> zooto()
> {
> data = 0;
> for (int i = 0; i < sizeof(bytes); i++) {
> bytes[ i ] = i;
> data += i;
> }
> cout << "zooto " << this << " default constructed" << endl;
> }

Be warned, that this loop will cause undefined behaviour,
if sizeof(int) != sizeof(char). The correct computation
of the array length is sizeof(bytes)/sizeof(bytes[0]).

> zooto( const zooto& obj ) : data( obj.data )
> {
> for (int i = 0; i < sizeof(bytes); i++)
> bytes[ i ] = obj.bytes[ i ];
> cout << "zooto " << this << " copy constructed" << endl;
> }
>
> zooto operator=(const zooto& obj) {
> cout << "zooto assigned " << this << endl;
> data = obj.data;
> for (int i = 0; i < sizeof(bytes); i++)
> bytes[ i ] = obj.bytes[ i ];
> return *this;
> }

Same defect for these two member functions as well.

> virtual ~zooto() {
> cout << "zooto " << this << " is being destroyed" << endl;
> }
>
> void runme() {
> data *= 2;
> }
>
> };
>
> struct testo {
> zooto test1,
> test2;
> };
>
> int test() {
> testo test1, test2;
>
> cout << "assignment!!!" << endl;
> test1 = test2;
>
> cout << "destruct!!!" << endl;
> return 0;
> }
>
> int main() {
> cout << "!!!Hello Worldxx!!!" << endl; // prints !!!Hello World!!!

This output looks odd and shouldn't happen.
(At least I would not expect that it would happen
before you created any zooto object, which's
implementation is probably buggy).

> test();
> return 0;
> }

HTH & Greetings from Bremen,

Daniel Kr�gler

stork

unread,
Nov 24, 2009, 12:55:36 AM11/24/09
to

> You must have been one of the very first C++ users. I vaguely remember
> Stroustrup writing that in some of the earliest C++ compilers, copy
> was bitwise, but my guess is that this was changed in '95. But not on
> your compiler, apparently.

Borland Turbo C++, Microsoft Visual C++ starting at 1.5, 1992-1995...
probably a Visual C++ bug that I've just remembered...

Francis Glassborow

unread,
Nov 24, 2009, 11:01:14 AM11/24/09
to
Neil Butterworth wrote:
> Francis Glassborow wrote:
>> I am at a loss to understand where you got the idea that copying would
>> default to bitwise (It is in C but then C does not have ctors so what
>> else could copying mean?. Nobody who has used C++ other than trivially
>> would expect anything other than memberwise copying. That is the only
>> way it has been over the two decades that I have been using C++.
>
> To quote from The Design & Evolution of C++, section 11.4.4:
>
> "Originally, assignment and initialisation were by default defined as
> bitwise copy."
>
> Unfortunately, Stroustrup doesn't say (at least in the quoted section)
> when this changed to memberwise copy - I seem to remember it was at
> Cfront 2.9, but I could easily be wrong.
>
> Neil Butterworth
>
The copyright date for D&E is 1994 which effectively means that it was
written in 1993. Clearly the initialisation rule had changed by then and
the exact phrasing of Bjarne's statement would suggest that it was some
years prior to the time of writing. Your recollection that the change
happened in Cfront 2.9 would fit that (Cfront 3.0 was released in 1991.
I cannot find my copy of the ARM which might shed more light as it was
written before 1990 (copyright date was January 1990)

Andrew Browne

unread,
Nov 24, 2009, 11:02:38 AM11/24/09
to

On 24 Nov, 05:35, Neil Butterworth <nbutterworth1...@gmail.com> wrote:
> Unfortunately, Stroustrup doesn't say (at least in the quoted section)
> when this changed to memberwisecopy- I seem to remember it was at

> Cfront 2.9, but I could easily be wrong.

It was with Cfront 2.0 (which is probably what you meant) in 1989. My
first experience with C++ was earlier that year with Cfront 1.2 (or
the Glockenspiel PC port of it to be precise.) This used to issue a
warning message that copying was bitwise by default.

Andrew

alapaa

unread,
Nov 24, 2009, 11:00:57 AM11/24/09
to
On Nov 23, 12:30 pm, stork <tbandrow...@treatyist.com> wrote:
> I had always thought that C++, if you did not make an explicit copy
> constructor and assignment operator, copying would be bitwise, as if a
> ...

Correct me if I'm wrong, but it seems that the hack below shows that
at least
a character member is not copied memberwise, instead at least the
whole 32-bit
word containing the member is copied (note that I write the char 'A'
into the
3-byte padding that follows the .ch member), then copy):

(compiled on gcc 4.X on Ubuntu)


#include <iostream>

using std::cout;

class Stuff {
public:
int int1;
double double1;
char ch;
};

int main()
{
Stuff stuff1;

cout << "sizeof(int): " << sizeof(int) << '\n';
cout << "sizeof(double): " << sizeof(double) << '\n';
cout << "sizeof(stuff): " << sizeof(Stuff) << '\n';

char* foobar1 = &stuff1.ch;
char* foobar2 = reinterpret_cast<char*>(&stuff1);
cout << "Address diff: " << foobar1 - foobar2 << '\n';

foobar1++;
*foobar1 = 'A';

Stuff stuff2;

stuff2 = stuff1; // Memberwise copy?

cout << "Contents after ch in stuff2: " << *(&stuff2.ch+1) <<
'\n';

Neil Butterworth

unread,
Nov 24, 2009, 3:38:29 PM11/24/09
to
Francis Glassborow wrote:
> Neil Butterworth wrote:
>> Francis Glassborow wrote:
>>> I am at a loss to understand where you got the idea that copying would
>>> default to bitwise (It is in C but then C does not have ctors so what
>>> else could copying mean?. Nobody who has used C++ other than trivially
>>> would expect anything other than memberwise copying. That is the only
>>> way it has been over the two decades that I have been using C++.
>>
>> To quote from The Design & Evolution of C++, section 11.4.4:
>>
>> "Originally, assignment and initialisation were by default defined as
>> bitwise copy."
>>
>> Unfortunately, Stroustrup doesn't say (at least in the quoted section)
>> when this changed to memberwise copy - I seem to remember it was at
>> Cfront 2.9, but I could easily be wrong.
>>
> The copyright date for D&E is 1994 which effectively means that it was
> written in 1993. Clearly the initialisation rule had changed by then and
> the exact phrasing of Bjarne's statement would suggest that it was some
> years prior to the time of writing. Your recollection that the change
> happened in Cfront 2.9 would fit that (Cfront 3.0 was released in 1991.
> I cannot find my copy of the ARM which might shed more light as it was
> written before 1990 (copyright date was January 1990)

Cfront 2.9 was of course a typo on my part - I meant 2.0. I had a quick
look in my copy of the ARM (first time I've opened it in many a long
year) but couldn't find anything.

Neil Butterworth

Neil Butterworth

unread,
Nov 24, 2009, 3:39:55 PM11/24/09
to
Francis Glassborow wrote:
>>
>> Unfortunately, Stroustrup doesn't say (at least in the quoted section)
>> when this changed to memberwise copy - I seem to remember it was at
>> Cfront 2.9, but I could easily be wrong.

> The copyright date for D&E is 1994 which effectively means that it was


> written in 1993. Clearly the initialisation rule had changed by then and
> the exact phrasing of Bjarne's statement would suggest that it was some
> years prior to the time of writing. Your recollection that the change
> happened in Cfront 2.9 would fit that (Cfront 3.0 was released in 1991.
> I cannot find my copy of the ARM which might shed more light as it was
> written before 1990 (copyright date was January 1990)

Further spelunking in the D&E book reveals this, from section 5.2
Release 2.0 subsection 5.2.1 Feature Overview:

"[4] Recursive definition of assignment and initialization (11.4.4)"

By recursive, he means memberwise, so I think this is definitive: prior
to the release of Cfront 2.0, which came out in June 1989 (according to
D&E) assignment and copying was bitwise.


Neil Butterworth

Neil Butterworth

unread,
Nov 24, 2009, 3:38:53 PM11/24/09
to
Andrew Browne wrote:
> On 24 Nov, 05:35, Neil Butterworth <nbutterworth1...@gmail.com> wrote:
>> Unfortunately, Stroustrup doesn't say (at least in the quoted section)
>> when this changed to memberwisecopy- I seem to remember it was at
>> Cfront 2.9, but I could easily be wrong.
>
> It was with Cfront 2.0 (which is probably what you meant) in 1989. My
> first experience with C++ was earlier that year with Cfront 1.2 (or
> the Glockenspiel PC port of it to be precise.) This used to issue a
> warning message that copying was bitwise by default.

Yes, I did mean 2.0.

Good to know that at least one other person remembers the Glockenspiel
compiler. I had to use it when I first started teaching at The
Instruction Set (anyone remember them?) - it had the unendearing habit
of core dumping (or the OS/2 equivalent) when it came across C++ source
code it didn't like - not what you want when introducing people to a new
programming language. We soon changed to Oregon (?) C++ running on UNIX
and then to IBM's AIX compiler, which was actually pretty good.

Neil Butterworth

Francis Glassborow

unread,
Nov 25, 2009, 9:14:27 AM11/25/09
to
Neil Butterworth wrote:
> Francis Glassborow wrote:
>>>
>>> Unfortunately, Stroustrup doesn't say (at least in the quoted section)
>>> when this changed to memberwise copy - I seem to remember it was at
>>> Cfront 2.9, but I could easily be wrong.
>
>> The copyright date for D&E is 1994 which effectively means that it was
>> written in 1993. Clearly the initialisation rule had changed by then and
>> the exact phrasing of Bjarne's statement would suggest that it was some
>> years prior to the time of writing. Your recollection that the change
>> happened in Cfront 2.9 would fit that (Cfront 3.0 was released in 1991.
>> I cannot find my copy of the ARM which might shed more light as it was
>> written before 1990 (copyright date was January 1990)
>
> Further spelunking in the D&E book reveals this, from section 5.2
> Release 2.0 subsection 5.2.1 Feature Overview:
>
> "[4] Recursive definition of assignment and initialization (11.4.4)"
>
> By recursive, he means memberwise, so I think this is definitive: prior
> to the release of Cfront 2.0, which came out in June 1989 (according to
> D&E) assignment and copying was bitwise.


Thanks. And 1989 was two decades ago :) So I guess I was right in so far
as having used memberwise copying for 2 decades but wrong in the sense
that it was not always so.

Francis Glassborow

unread,
Nov 25, 2009, 9:14:36 AM11/25/09
to
alapaa wrote:
> On Nov 23, 12:30 pm, stork <tbandrow...@treatyist.com> wrote:
>> I had always thought that C++, if you did not make an explicit copy
>> constructor and assignment operator, copying would be bitwise, as if a
>> ...
>
> Correct me if I'm wrong, but it seems that the hack below shows that
> at least
> a character member is not copied memberwise, instead at least the
> whole 32-bit
> word containing the member is copied (note that I write the char 'A'
> into the
> 3-byte padding that follows the .ch member), then copy):
>


What happens to padding bits is unspecified so there is nothing to
prevent them being either copied or ignored. And there is no way to
distinguish between bitwise and memberwise copying of builtin types.
Your program does nothing other than to demonstrate that this particular
platform elects to copy the whole 4-bytes (and on quite a few systems
that would be faster than copying just a single char.)

alapaa

unread,
Nov 25, 2009, 12:53:30 PM11/25/09
to
On Nov 25, 3:14 pm, Francis Glassborow
<francis.glassbo...@btinternet.com> wrote:

> What happens to padding bits is unspecified so there is nothing to
> prevent them being either copied or ignored. And there is no way to
> distinguish between bitwise and memberwise copying of builtin types.
> Your program does nothing other than to demonstrate that this particular
> platform elects to copy the whole 4-bytes (and on quite a few systems
> that would be faster than copying just a single char.)

It is not surprising that the whole 4-bytes get copied. In fact, it
would be
interesting to know if there are platforms out there that go out of
their way
to copy only the char, and not the surrounding padding. I have not
made a
disassembly of the code, maybe memcpy() is the default for POD types
in e.g. gcc?

0 new messages