472,371 Members | 1,607 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,371 software developers and data experts.

is a memcpy() equivalent to the default copy constructor?

QUESTION:

In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?

(b) If not, is the behavior for lines 36-39 well defined by the
standard?

While all C++ compilers I know of implement virtual functions by
storing a pointer to a vtable in the object the standard doesn't talk
about implementation details like this ...

Regards,
--jfc

1 #include <iostream>
2 #include <cstdlib>
3
4 class foo {
5 public:
6 int i;
7 foo(): i(3) {}
8 virtual void f() { std::cout << "foo" << std::endl; }
9 virtual ~foo() {};
10 };
11
12 class bish : public foo {
13 public:
14 int j;
15 double d;
16
17 bish(int p): j(p), d(0.0) {}
18 void f() { std::cout << "bish" << std::endl; }
19 ~bish() {};
20 };
21
22 int
23 main(int argc,char *argv[])
24 {
25 char buf1[sizeof(bish)];
26
27 bish b1(99);
28
29 // consttruct with placement new.
30 bish * b2 = new((void *)buf1) bish(42);
31
32 // copying with the default copy ctor
33 bish b3(b1);
34
35 // equivalent to copy construction?
36 bish * b4 = (bish *) new char[sizeof(bish)];
37 memcpy((char *)b4, (char *)&b1, sizeof(bish));
38
39 b4->f();
40 }
41
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #1
16 8391

"jonathan cano" <fu****@gmail.com> skrev i en meddelelse
news:11**********************@o13g2000cwo.googlegr oups.com...
QUESTION:

In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?
Nope.

(b) If not, is the behavior for lines 36-39 well defined by the
standard?
You could say so. The behaviour is "undefined".
You also seem to have a problem with alignment. buf1 will NOT be aligned
properly for a foo structure, and I do not believe that bish4 is required to
be properly aligned (although i am not completely sure here).

While all C++ compilers I know of implement virtual functions by
storing a pointer to a vtable in the object the standard doesn't talk
about implementation details like this ... Correct.
Regards,
--jfc

[snip]

/Peter
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #2
Hi,

jonathan cano wrote:
In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?
No, there is no such guarantee.
The most problematic are virtual functions in the foo class, although it
might as weel appear to work on some platforms.
(b) If not, is the behavior for lines 36-39 well defined by the
standard?


No. You cannot memcpy non-POD types.

Moreover, I think there is no guarantee that new char[] will allocate
the memory block that is correctly aligned for bish (b4 in your code).
Certainly, there is no such guarantee for local char[] arrays (buf1 in
your code).

This could be another problem in your code. Not what you're asking
about, but still important.

--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #3
jonathan cano wrote:
QUESTION:

In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?

(b) If not, is the behavior for lines 36-39 well defined by the
standard?

While all C++ compilers I know of implement virtual functions by
storing a pointer to a vtable in the object the standard doesn't talk
about implementation details like this ...

Regards,
--jfc
[snip]
30 bish * b2 = new((void *)buf1) bish(42); 36 bish * b4 = (bish *) new char[sizeof(bish)];
37 memcpy((char *)b4, (char *)&b1, sizeof(bish));


Copy construction is a member-wise operation; the object is initialized
as if the copy constructors of each member where invoked. Typically,
the copy constructors of each member are invoked.

For certain classes (PODs), this may be equivalent to memcpy, but in
general it is not.

In the case of classes with virtual functions, memcpy is almost
certainly the wrong thing; for example:

struct A { virtual f() { cout << "A::f"; } };
struct B : public A { virtual f() { cout << "B::f"; } };

B b;
A a(b); // copy ctor A::A is called here.

In this case, memcpying some part of B into A is, at best, Undefined
Behavior.
--
A. Kanawati
NO*************@comcast.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #4
In general, the default copy constructor calls operator= on each data
member of the class, so if you have, for instance, a shared pointer in
your class, the memcpy wouldn't update the count, while the default
copy constructor would.

In this specific example, you would probably be okay, in practical
terms, but according to the standard, the results are undefined.

Joel Redman
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #5
Joel wrote:
In general, the default copy constructor calls operator= on
each data member of the class


Actually it calls the copy constructor on each data member.

The default operator= would call operator= on its data members.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #6
RH
Note that modern compilers (e.g. Intel's or HP's) have a phase that
tries to determine which would be the best way to default copy an
object. memcpy() is usually not as good as member-by-member copy for
smaller objects, but better for larger objects.

The compilers employ all kinds of heuristics to make this fast. If you
profile-see a bottleneck there - try a better compiler ;-)

-- RH
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #7
RH
Note that modern compilers (e.g. Intel's or HP's) have a phase that
tries to determine which would be the best way to default copy an
object. memcpy() is usually not as good as member-by-member copy for
smaller objects, but better for larger objects.

The compilers employ all kinds of heuristics to make this fast. If you
profile-see a bottleneck there - try a better compiler ;-)

-- RH
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #8
Joel wrote:
In general, the default copy constructor calls operator= on each data
member of the class, so if you have, for instance, a shared pointer in
your class, the memcpy wouldn't update the count, while the default
copy constructor would.


Operator= is NOT copy construction. The copy-ctor call the copy-ctors
of the members. To call operator= you need two already constructed
objects.
--
A. Kanawati
NO*************@comcast.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #9
"Joel" <re******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
In general, the default copy constructor calls operator= on each data
member of the class...


No, it doesn't -- it calls the copy constructor on each data member of the
class.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jul 23 '05 #10
I sit corrected. .

The important point is that memcpy is not called, to prevent improper
construction of things with nontrivial construction. In the event that
you do have a trivial construction, the compiler may very well optimize
this to a memcpy, but you cannot say that a-priori.

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

Jul 23 '05 #11
Maciej Sobczak write "ms>":
ms> Moreover, I think there is no guarantee that new char[] will
ms> allocate the memory block that is correctly aligned for bish (b4
ms> in your code).> Certainly, there is no such guarantee for local
ms> char[] arrays (buf1 in your code).

Thanks for pointing that out.

presumably my original code sample could be fixed like this:

25 char buf1[sizeof(bish) + ALIGNMENT_BYTES];
+ char *cp = buf1;

+ while (not_aligned(cp)) ++cp;

30 bish * b2 = new((void *)cp) bish(42);

Which leaves the question: Is there a portable way to align a pointer
so that it meets a platforms strictest alignment requirements or is
such code doomed to non-portability?

It seems technically feasible that this could be included in a
language standard although time and/or politics may have kept it out of
ISO 14882.

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

Jul 23 '05 #12
jonathan cano wrote:
Maciej Sobczak write "ms>":
ms> Moreover, I think there is no guarantee that new char[] will
ms> allocate the memory block that is correctly aligned for bish (b4
ms> in your code).> Certainly, there is no such guarantee for local
ms> char[] arrays (buf1 in your code).

Thanks for pointing that out.

presumably my original code sample could be fixed like this:

25 char buf1[sizeof(bish) + ALIGNMENT_BYTES];
+ char *cp = buf1;

+ while (not_aligned(cp)) ++cp;

30 bish * b2 = new((void *)cp) bish(42);

Which leaves the question: Is there a portable way to align a pointer
so that it meets a platforms strictest alignment requirements or is
such code doomed to non-portability?

It seems technically feasible that this could be included in a
language standard although time and/or politics may have kept it out of
ISO 14882.

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


From 'man malloc':

"For calloc() and malloc(), the value returned is a pointer to the
allocated memory, which is suitably aligned for any kind of variable,
or NULL if the request fails."

So, memory obtained via malloc() and family is suitably aligned
for any type, including pointers.

Regards,
Larry
--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #13
jonathan cano wrote:
Maciej Sobczak write "ms>":
ms> Moreover, I think there is no guarantee that new char[] will
ms> allocate the memory block that is correctly aligned for bish (b4
ms> in your code).> Certainly, there is no such guarantee for local
ms> char[] arrays (buf1 in your code).

Thanks for pointing that out.

presumably my original code sample could be fixed like this:

25 char buf1[sizeof(bish) + ALIGNMENT_BYTES];
+ char *cp = buf1;

+ while (not_aligned(cp)) ++cp;

30 bish * b2 = new((void *)cp) bish(42);


The only "small issue" is to compute ALIGNMENT_BYTES and implement the
not_aligned() predicate - note that it depends on the *type* you want to
align.
Even experts brake their fingers on this.

Certainly, malloc() and realloc() are required to return a pointer that
meets the strictest alignment guarantee for all fundamental types.
In practice, it should safely work for classes as well.

--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/

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

Jul 23 '05 #14

"Larry I Smith" <la***********@verizon.net> skrev i en meddelelse
news:Nzi9e.17695$jd6.749@trnddc07...
jonathan cano wrote:
Maciej Sobczak write "ms>":
ms> Moreover, I think there is no guarantee that new char[] will
ms> allocate the memory block that is correctly aligned for bish (b4
ms> in your code).> Certainly, there is no such guarantee for local
ms> char[] arrays (buf1 in your code).

Thanks for pointing that out.

presumably my original code sample could be fixed like this:

25 char buf1[sizeof(bish) + ALIGNMENT_BYTES];
+ char *cp = buf1;

+ while (not_aligned(cp)) ++cp;

30 bish * b2 = new((void *)cp) bish(42);

Which leaves the question: Is there a portable way to align a pointer
so that it meets a platforms strictest alignment requirements or is
such code doomed to non-portability?

It seems technically feasible that this could be included in a
language standard although time and/or politics may have kept it out of
ISO 14882.

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

From 'man malloc':

"For calloc() and malloc(), the value returned is a pointer to the
allocated memory, which is suitably aligned for any kind of variable,
or NULL if the request fails."

So, memory obtained via malloc() and family is suitably aligned
for any type, including pointers.


This is C, not C++. For C++ operator new only guarantees suitable alignment
for the type one is newing for.

/Peter
Regards,
Larry
--
Anti-spam address, change each 'X' to '.' to reply directly.

Jul 23 '05 #15
Peter Koch Larsen wrote:
"Larry I Smith" <la***********@verizon.net> skrev i en meddelelse
news:Nzi9e.17695$jd6.749@trnddc07...
jonathan cano wrote:
Maciej Sobczak write "ms>":
ms> Moreover, I think there is no guarantee that new char[] will
ms> allocate the memory block that is correctly aligned for bish (b4
ms> in your code).> Certainly, there is no such guarantee for local
ms> char[] arrays (buf1 in your code).

Thanks for pointing that out.

presumably my original code sample could be fixed like this:

25 char buf1[sizeof(bish) + ALIGNMENT_BYTES];
+ char *cp = buf1;

+ while (not_aligned(cp)) ++cp;

30 bish * b2 = new((void *)cp) bish(42);

Which leaves the question: Is there a portable way to align a pointer
so that it meets a platforms strictest alignment requirements or is
such code doomed to non-portability?

It seems technically feasible that this could be included in a
language standard although time and/or politics may have kept it out of
ISO 14882.

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

From 'man malloc':

"For calloc() and malloc(), the value returned is a pointer to the
allocated memory, which is suitably aligned for any kind of variable,
or NULL if the request fails."

So, memory obtained via malloc() and family is suitably aligned
for any type, including pointers.


This is C, not C++. For C++ operator new only guarantees suitable alignment
for the type one is newing for.

/Peter
Regards,
Larry
--
Anti-spam address, change each 'X' to '.' to reply directly.



IIRC, the 'C' functions are part of C++.

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #16

"Larry I Smith" <la***********@verizon.net> skrev i en meddelelse
news:WHB9e.24712$jd6.18946@trnddc07...
Peter Koch Larsen wrote:
"Larry I Smith" <la***********@verizon.net> skrev i en meddelelse
news:Nzi9e.17695$jd6.749@trnddc07...
jonathan cano wrote:
Maciej Sobczak write "ms>":
ms> Moreover, I think there is no guarantee that new char[] will
ms> allocate the memory block that is correctly aligned for bish (b4
ms> in your code).> Certainly, there is no such guarantee for local
ms> char[] arrays (buf1 in your code).

Thanks for pointing that out.

presumably my original code sample could be fixed like this:

25 char buf1[sizeof(bish) + ALIGNMENT_BYTES];
+ char *cp = buf1;

+ while (not_aligned(cp)) ++cp;

30 bish * b2 = new((void *)cp) bish(42);

Which leaves the question: Is there a portable way to align a pointer
so that it meets a platforms strictest alignment requirements or is
such code doomed to non-portability?

It seems technically feasible that this could be included in a
language standard although time and/or politics may have kept it out of
ISO 14882.

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

From 'man malloc':

"For calloc() and malloc(), the value returned is a pointer to the
allocated memory, which is suitably aligned for any kind of variable,
or NULL if the request fails."

So, memory obtained via malloc() and family is suitably aligned
for any type, including pointers.
This is C, not C++. For C++ operator new only guarantees suitable
alignment
for the type one is newing for.

/Peter
Regards,
Larry
--
Anti-spam address, change each 'X' to '.' to reply directly.



IIRC, the 'C' functions are part of C++.

Of course, but the OP specifically used new [], not malloc. If you read the
C++ standard, you will note that new does not have to be implemented via
malloc.

/Peter Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.

Jul 23 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: A | last post by:
Hi, A default copy constructor is created for you when you don't specify one yourself. In such case, the default copy constructor will simply do a bitwise copy for primitives (including...
3
by: Bob | last post by:
Hi, If a class contains only built-in types and standard library objects such as strings and vectors, is it safe to let the compiler create the copy constructor and assignment operator, or is it...
4
by: PengYu.UT | last post by:
I have the following program. The auto_ptr cause the compile error. When I change auto_ptr to pointer, the error gone. Would you please help me to understand what is wrong? ...
4
by: Jeevang | last post by:
Hi, We need copy constructor when we are passing the object to a function or if the function returns any object. Suppose if we haven't defined the user defined copy constructor, it will give a...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
1
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.