By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,197 Members | 988 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,197 IT Pros & Developers. It's quick & easy.

Default ctor, etc generated by compiler for structs?

P: n/a
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not explicitely
defined?

I think the answer is yes, because "there is no difference between a struct
and a class except the public/private access specification" (and a few minor
other things). When I create a class, I always start by declaring the
default constructor, copy constructor and assignment operator private with
no implementation. I don't do that for structs though (I consider structs
like they were in C, but they really are not in the implementation as far as
I know). I'm thinking that I don't handle structs the same because I trust
the compiler to do the right thing in the case of structs whereas bitwise
copy for a class may not be what is desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?

John

Jun 15 '07 #1
Share this Question
Share on Google+
43 Replies


P: n/a

JohnQ <jo***********************@yahoo.comwrote in message...
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely
defined?
#include <vector>
struct Hmmm{ int mmm; };

{
std::vector<HmmmSVmmm(2);
std::vector<HmmmSVtwo;
SVtwo = SVmmm;
}

Can that work? Does it meet the requirements for a std container?
[ my tests say: yes, no problem, dude! ]
Now, add something non-simple to the struct, and test again.

>
I think the answer is yes, because "there is no difference between a
struct
and a class except the public/private access specification" (and a few
minor
other things). When I create a class, I always start by declaring the
default constructor, copy constructor and assignment operator private with
no implementation. I don't do that for structs though (I consider structs
like they were in C, but they really are not in the implementation as far
as
I know). I'm thinking that I don't handle structs the same because I trust
the compiler to do the right thing in the case of structs whereas bitwise
copy for a class may not be what is desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?
John
class A{ public: int a;}; == struct A{ int a;};
class A{ int a;}; == struct A{ private: int a;};

Or did I misunderstand something (again!).

--
Bob R
POVrookie
Jun 16 '07 #2

P: n/a
JohnQ wrote:
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification" (and
a few minor other things). When I create a class, I always start by
declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are not
in the implementation as far as I know). I'm thinking that I don't
handle structs the same because I trust the compiler to do the right
thing in the case of structs whereas bitwise copy for a class may not be
what is desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?
Apply the same rules as you apply to your classes. If you need to
initialise members on creation or copy, you need constructors.

--
Ian Collins.
Jun 16 '07 #3

P: n/a
"JohnQ" <jo***********************@yahoo.comwrote in message
news:Hy*****************@newssvr19.news.prodigy.ne t...
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification" (and a
few minor other things). When I create a class, I always start by
declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are not in
the implementation as far as I know). I'm thinking that I don't handle
structs the same because I trust the compiler to do the right thing in the
case of structs whereas bitwise copy for a class may not be what is
desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?
If your structure is POD, then there should be no reason not to allow the
compiler to create default constructor, destrucctor, copy constructor and
assignment operators. I would say it was okay, but I do not know for
exactly what reason you crete the 4 for classes (not saying it's a bad
thing, probably a very good thing, I just don't know your reasoning behind
it).
Jun 16 '07 #4

P: n/a
JohnQ wrote:
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?
If by a struct you mean POD, then yes, but only conceptually.
If by a struct you mean any class where you only specify data
members, then it depends on the data members.
I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification"
(and a few minor other things). When I create a class, I always start
by declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are
not in the implementation as far as I know). I'm thinking that I
don't handle structs the same because I trust the compiler to do the
right thing in the case of structs whereas bitwise copy for a class
may not be what is desired, for example.
What's "bitwise copy"? I don't know of that concept in C++.
Is the above reasoning OK? Should I continue NOT declaring/defining
the default stuff for structs?
It's up to you. And the ability of the compiler to generate the
functions you don't declare/define depends on the data members.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 16 '07 #5

P: n/a
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:gu******************************@comcast.com. ..
JohnQ wrote:
>Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

If by a struct you mean POD, then yes, but only conceptually.
If by a struct you mean any class where you only specify data
members, then it depends on the data members.
>I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification"
(and a few minor other things). When I create a class, I always start
by declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are
not in the implementation as far as I know). I'm thinking that I
don't handle structs the same because I trust the compiler to do the
right thing in the case of structs whereas bitwise copy for a class
may not be what is desired, for example.

What's "bitwise copy"? I don't know of that concept in C++.
It's a rather well known term:
http://www.glenmccl.com/glos.htm#tag017
>Is the above reasoning OK? Should I continue NOT declaring/defining
the default stuff for structs?

It's up to you. And the ability of the compiler to generate the
functions you don't declare/define depends on the data members.

Jun 16 '07 #6

P: n/a
On 16 Jun, 07:45, "Jim Langston" <tazmas...@rocketmail.comwrote:
"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message

news:gu******************************@comcast.com. ..
JohnQ wrote:
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?
<snip>
I'm thinking that I
don't handle structs the same because I trust the compiler to do the
right thing in the case of structs whereas bitwise copy for a class
may not be what is desired, for example.
What's "bitwise copy"? I don't know of that concept in C++.

It's a rather well known term:http://www.glenmccl.com/glos.htm#tag017
Perhaps, but it's not defined in C++. Of more direct relevance to the
OP though is that, regardless of whether we're all happy with that
definition of "bitwise copy", it's not what happens in the implicitly-
defined copy constructor, which does a memberwise copy.

Gavin Deane

Jun 16 '07 #7

P: n/a
On Jun 15, 7:59 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
JohnQ <johnqREMOVETHISprogram...@yahoo.comwrote in message...
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely
defined?

#include <vector>
struct Hmmm{ int mmm; };

{
std::vector<HmmmSVmmm(2);
std::vector<HmmmSVtwo;
SVtwo = SVmmm;

}

Can that work? Does it meet the requirements for a std container?
[ my tests say: yes, no problem, dude! ]
Now, add something non-simple to the struct, and test again.
Your program is not a right e.g for the question asked. I think this
would have been misunderstood by query submitter. In this case,
actually, vector template class will take care of constructor stuff
for statement "std::vector<HmmmSVmmm(2);", it's not default ctr of
struct Hmmm.

- Bharath

Jun 16 '07 #8

P: n/a
On 16 Jun, 10:48, Bharath <bharath.donni...@gmail.comwrote:
On Jun 15, 7:59 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
JohnQ <johnqREMOVETHISprogram...@yahoo.comwrote in message...
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely
defined?
#include <vector>
struct Hmmm{ int mmm; };
{
std::vector<HmmmSVmmm(2);
std::vector<HmmmSVtwo;
SVtwo = SVmmm;
}
Can that work? Does it meet the requirements for a std container?
[ my tests say: yes, no problem, dude! ]
Now, add something non-simple to the struct, and test again.

Your program is not a right e.g for the question asked. I think this
would have been misunderstood by query submitter. In this case,
actually, vector template class will take care of constructor stuff
for statement "std::vector<HmmmSVmmm(2);"
Yes, and one of the things the vector constuctor will do is to default-
construct 2 objects of type to populate SVmmm.
it's not default ctr of
struct Hmmm.
The default constructor of Hmmm is necessary and is used. The code
demonstarates that struct Hmmm does have an implicitly-defined default
constructor and so does address the OP's question.

Gavin Deane

Jun 16 '07 #9

P: n/a

Bharath wrote in message...
>
Your program is not a right e.g for the question asked. I think this
would have been misunderstood by query submitter. In this case,
actually, vector template class will take care of constructor stuff
for statement "std::vector<HmmmSVmmm(2);", it's not default ctr of
struct Hmmm.
- Bharath
See this thread if you have doubts:

----- Original Message -----
From: BobR
Newsgroups: comp.lang.c++
Sent: Saturday, June 09, 2007 10:41 PM
Subject: Re: problems of storing dynamically created objects in a vector

--
Bob R
POVrookie
Jun 16 '07 #10

P: n/a

BobR wrote in message...
>
#include <vector>
struct Hmmm{ int mmm; };

{
std::vector<HmmmSVmmm(2);
// add this to demonstrate the assignment operator is there:
SVmmm.at(0).mmm = 42;
SVmmm.at(1) = SVmmm.at(0); // use assignment
// cout<<SVmmm.at(1).mmm;

// std::vector<HmmmSVtwo;
// SVtwo = SVmmm; // oops, copied the vector, not Hmmm assign
}
--
Bob R
POVrookie
Jun 16 '07 #11

P: n/a
On Jun 16, 12:15 pm, Gavin Deane <deane_ga...@hotmail.comwrote:
On 16 Jun, 10:48, Bharath <bharath.donni...@gmail.comwrote:
On Jun 15, 7:59 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
JohnQ <johnqREMOVETHISprogram...@yahoo.comwrote in message...
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely
defined?
#include <vector>
struct Hmmm{ int mmm; };
{
std::vector<HmmmSVmmm(2);
std::vector<HmmmSVtwo;
SVtwo = SVmmm;
}
Can that work? Does it meet the requirements for a std container?
[ my tests say: yes, no problem, dude! ]
Now, add something non-simple to the struct, and test again.
Your program is not a right e.g for the question asked. I think this
would have been misunderstood by query submitter. In this case,
actually, vector template class will take care of constructor stuff
for statement "std::vector<HmmmSVmmm(2);"
Yes, and one of the things the vector constuctor will do is to
default-construct 2 objects of type to populate SVmmm.
Just a nit, but the vector constructor will not
default-construct 2 objects. The compiler will
default-construct an argument to vector, which will copy this
object into the 2 objects in the vector.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 16 '07 #12

P: n/a

"Ian Collins" <ia******@hotmail.comwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
>Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification" (and
a few minor other things). When I create a class, I always start by
declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are not
in the implementation as far as I know). I'm thinking that I don't
handle structs the same because I trust the compiler to do the right
thing in the case of structs whereas bitwise copy for a class may not be
what is desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?
Apply the same rules as you apply to your classes. If you need to
initialise members on creation or copy, you need constructors.
I was pondering the technique of restricting default constructor, copy
constructor, assignment operator though and its validity for structs as well
as classes:

class A
{
A(); // disallow def construction
A(const A&); // disallow copy construction
const A& operator=(const A&); // disallow assignment

public
int data_member;

A(int arg)
: data_member(arg) {}
};

struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

int data_member; // public by default

B(int arg)
: data_member(arg) {}
};

If I disallow the stuff in struct B, it acts less like a C struct, yes?

John

Jun 16 '07 #13

P: n/a
On 16 Jun, 20:14, James Kanze <james.ka...@gmail.comwrote:
On Jun 16, 12:15 pm, Gavin Deane <deane_ga...@hotmail.comwrote:
On 16 Jun, 10:48, Bharath <bharath.donni...@gmail.comwrote:
On Jun 15, 7:59 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
JohnQ <johnqREMOVETHISprogram...@yahoo.comwrote in message...
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely
defined?
#include <vector>
struct Hmmm{ int mmm; };
{
std::vector<HmmmSVmmm(2);
std::vector<HmmmSVtwo;
SVtwo = SVmmm;
}
Can that work? Does it meet the requirements for a std container?
[ my tests say: yes, no problem, dude! ]
Now, add something non-simple to the struct, and test again.
Your program is not a right e.g for the question asked. I think this
would have been misunderstood by query submitter. In this case,
actually, vector template class will take care of constructor stuff
for statement "std::vector<HmmmSVmmm(2);"
Yes, and one of the things the vector constuctor will do is to
default-construct 2 objects of type to populate SVmmm.

Just a nit, but the vector constructor will not
default-construct 2 objects. The compiler will
default-construct an argument to vector, which will copy this
object into the 2 objects in the vector.
.... thereby demonstrating the presence of an implicitly-defined copy
constructor for struct Hmmm as well as an implicitly-defined default
constructor - handily addressing even more of the OP's question.

Thanks for the nit.

Gavin Deane

Jun 16 '07 #14

P: n/a
JohnQ wrote:
[..]
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

int data_member; // public by default

B(int arg)
: data_member(arg) {}
};

If I disallow the stuff in struct B, it acts less like a C struct,
yes?
As soon as you add a c-tor to B, it stops being a POD. Whether you
"disallow the stuff" or not does not matter after that, it's not
"a C struct" any more.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 16 '07 #15

P: n/a

"Jim Langston" <ta*******@rocketmail.comwrote in message
news:O0*************@newsfe06.lga...
"JohnQ" <jo***********************@yahoo.comwrote in message
news:Hy*****************@newssvr19.news.prodigy.ne t...
>Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification" (and a
few minor other things). When I create a class, I always start by
declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are not
in the implementation as far as I know). I'm thinking that I don't handle
structs the same because I trust the compiler to do the right thing in
the case of structs whereas bitwise copy for a class may not be what is
desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?

If your structure is POD, then there should be no reason not to allow the
compiler to create default constructor, destrucctor, copy constructor and
assignment operators.
That's what I was thinking. I wasn't sure if the compiler generates those
things for a POD struct. Are you sure?
I would say it was okay, but I do not know for exactly what reason you
crete the 4 for classes (not saying it's a bad thing, probably a very good
thing, I just don't know your reasoning behind it).
To prevent those things from happening unknowingly for what could be a
non-POD.

John

Jun 16 '07 #16

P: n/a

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:gu******************************@comcast.com. ..
JohnQ wrote:
>Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

If by a struct you mean POD, then yes, but only conceptually.
Different from an identical class? Conceptually how?
If by a struct you mean any class where you only specify data
members, then it depends on the data members.
Lately, I've been pondering, "when does a struct stop being a struct?". To
me, that's when its not the same size as a C struct or not layed out the
same. So obviously, when a virtual function gets added, then "a struct stops
being a struct". I think I can add non-virtual member functions, non-virtual
destructor and operators ad infinitum and the "struct will still be a
struct" (right?). Even though some explicit syntax would make things more
evident:

struct A
{
int data;
};

struct B
{
int data;

B(int val){ data = val; } // OK, not virtual
};

class StructWrapper
{
A a_struct;

public:
A(int val){ a_struct.data = val; }
operator A&(){ return a_struct; }
};

Where struct B can be used identically to struct A or StructWrapper (I
hope!) as the layouts and sizes are the same (assume the operator is being
used for StructWrapper when I say "can be used identically").

sizeof(A)==sizeof(B)==sizeof(StructWrapper)

But a_struct in StructWrapper would have to be made public to guarantee the
same layout as A and B?
>I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification"
(and a few minor other things). When I create a class, I always start
by declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are
not in the implementation as far as I know). I'm thinking that I
don't handle structs the same because I trust the compiler to do the
right thing in the case of structs whereas bitwise copy for a class
may not be what is desired, for example.

What's "bitwise copy"? I don't know of that concept in C++.
The equivalent of doing a memcpy of the class or struct (whether I used the
right terminology or not I don't know... "bytewise" seems more appropriate).
>
>Is the above reasoning OK? Should I continue NOT declaring/defining
the default stuff for structs?

It's up to you. And the ability of the compiler to generate the
functions you don't declare/define depends on the data members.
OK, so from what I gather, the compiler may or may not generate the
functions/operators depending on the data members. Is it that if there is
any non-POD data member, then the functions/operators get generated? Is it
always the full set (?): default constructor, copy constructor, assignment
operator, (destructor?).

John

Jun 16 '07 #17

P: n/a

"Gavin Deane" <de*********@hotmail.comwrote in message
news:11**********************@o61g2000hsh.googlegr oups.com...
On 16 Jun, 07:45, "Jim Langston" <tazmas...@rocketmail.comwrote:
>"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message

news:gu******************************@comcast.com ...
JohnQ wrote:
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

<snip>
>I'm thinking that I
don't handle structs the same because I trust the compiler to do the
right thing in the case of structs whereas bitwise copy for a class
may not be what is desired, for example.
What's "bitwise copy"? I don't know of that concept in C++.

It's a rather well known term:http://www.glenmccl.com/glos.htm#tag017

Perhaps, but it's not defined in C++. Of more direct relevance to the
OP though is that, regardless of whether we're all happy with that
definition of "bitwise copy", it's not what happens in the implicitly-
defined copy constructor, which does a memberwise copy.
That's interesting. Apparently "a struct is a struct" hardly ever! Oh wait,
does C do memberwise copy of structs also or bitwise?

John

Jun 16 '07 #18

P: n/a
JohnQ wrote:
>
"Ian Collins" <ia******@hotmail.comwrote:
>JohnQ wrote:
>>>
Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?
Apply the same rules as you apply to your classes. If you need to
initialise members on creation or copy, you need constructors.

I was pondering the technique of restricting default constructor, copy
constructor, assignment operator though and its validity for structs as
well as classes:
Why should the validity be any different?

As a hangover form C it is idiomatic in C++ to use an unadorned struct
as bucket of data.
>
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

int data_member; // public by default

B(int arg)
: data_member(arg) {}
};

If I disallow the stuff in struct B, it acts less like a C struct, yes?
Well it's obvious that it does.

--
Ian Collins.
Jun 16 '07 #19

P: n/a
JohnQ wrote:
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:gu******************************@comcast.com. ..
>JohnQ wrote:
>>Are a default constructor, destructor, copy constructor and
assignment operator generated by the compiler for a struct if they
are not explicitely defined?

If by a struct you mean POD, then yes, but only conceptually.

Different from an identical class?
What's "an identical class"? A class with the same order of its
members, all declared public? No difference.
Conceptually how?
Conceptually, every type has a destructor (or you can say that it
does, since you can call it). The standard has s concept of
"a pseudo-destructor call", which means that any type has at least
a pseudo-destructor. In my book you can say that a concept of
a destructor exists for every type. There is no code where the
CPU is led to perform some actions when an object of a POD type is
disposed of, yes. In that sense, a POD type does not have a d-tor.
So, conceptually, yes, physically, no.
>If by a struct you mean any class where you only specify data
members, then it depends on the data members.

Lately, I've been pondering, "when does a struct stop being a
struct?". To me, that's when its not the same size as a C struct or
not layed out the same. So obviously, when a virtual function gets
added, then "a struct stops being a struct". I think I can add
non-virtual member functions, non-virtual destructor and operators ad
infinitum and the "struct will still be a struct" (right?).
Nope. If we agree to substitute the words "C struct" with "POD",
then the Standard says that as soon as you add a user-defined c-tor,
it's not a POD any more, so not all non-virtual member functions
are "harmless" as far as POD-ness is concerned.
Even
though some explicit syntax would make things more evident:

struct A
{
int data;
};

struct B
{
int data;

B(int val){ data = val; } // OK, not virtual
};
Here, 'B' is not a POD class.
class StructWrapper
{
A a_struct;

public:
A(int val){ a_struct.data = val; }
You mean

StructWrapper(int val) { a_struct.data = val; }

, right?
operator A&(){ return a_struct; }
};

Where struct B can be used identically to struct A or StructWrapper (I
hope!) as the layouts and sizes are the same (assume the operator is
being used for StructWrapper when I say "can be used identically").
Nothing in the Standard says what the layouts are. We cannot rely on
their being the same.
sizeof(A)==sizeof(B)==sizeof(StructWrapper)
That doesn't matter.
But a_struct in StructWrapper would have to be made public to
guarantee the same layout as A and B?
Again, there is no way to "guarantee" what's not defined. There is
no definition of a complete class layout in the Standard.
>
>>I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification"
(and a few minor other things). When I create a class, I always
start by declaring the default constructor, copy constructor and
assignment operator private with no implementation. I don't do that
for structs though (I consider structs like they were in C, but
they really are not in the implementation as far as I know). I'm
thinking that I don't handle structs the same because I trust the
compiler to do the right thing in the case of structs whereas
bitwise copy for a class may not be what is desired, for example.

What's "bitwise copy"? I don't know of that concept in C++.

The equivalent of doing a memcpy of the class or struct (whether I
used the right terminology or not I don't know... "bytewise" seems
more appropriate).
Well, calling 'memcpy' upon copy-constructing an object is up to the
implementation. There is no way to know exactly what they do with
POD, most likely 'memcpy', or 'memmove', or some such. However, it
would be safer to assume that "memberwise copy" is performed, which
means that copy semantics for each member (provided they exist) are
invoked.
>>Is the above reasoning OK? Should I continue NOT declaring/defining
the default stuff for structs?

It's up to you. And the ability of the compiler to generate the
functions you don't declare/define depends on the data members.

OK, so from what I gather, the compiler may or may not generate the
functions/operators depending on the data members. Is it that if
there is any non-POD data member, then the functions/operators get
generated? Is it always the full set (?): default constructor, copy
constructor, assignment operator, (destructor?).
No, not always. For example, it's possible to copy-construct
a reference, but it's not possible to assign one, so if your class
has a data member that is a reference (it does make it non-POD, BTW),
then the copy c-tor can (and will) be generated but the copy
assignment op cannot (and will not) be.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 16 '07 #20

P: n/a
JohnQ wrote:
"Gavin Deane" <de*********@hotmail.comwrote in message
news:11**********************@o61g2000hsh.googlegr oups.com...
>On 16 Jun, 07:45, "Jim Langston" <tazmas...@rocketmail.comwrote:
>>"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message

news:gu******************************@comcast.co m...
JohnQ wrote:
Are a default constructor, destructor, copy constructor and
assignment operator generated by the compiler for a struct if
they are not explicitely defined?

<snip>
>>>>I'm thinking that I
don't handle structs the same because I trust the compiler to do
the right thing in the case of structs whereas bitwise copy for a
class may not be what is desired, for example.

What's "bitwise copy"? I don't know of that concept in C++.

It's a rather well known
term:http://www.glenmccl.com/glos.htm#tag017

Perhaps, but it's not defined in C++. Of more direct relevance to the
OP though is that, regardless of whether we're all happy with that
definition of "bitwise copy", it's not what happens in the
implicitly- defined copy constructor, which does a memberwise copy.

That's interesting. Apparently "a struct is a struct" hardly ever! Oh
wait, does C do memberwise copy of structs also or bitwise?
How would you determine the difference? If your members are all POD,
which means they essentially all boil down to built-in types, and
there are no references among them, their copy semantics are usually
just like "bitwise" or "bytewise" or "memcpy-like".

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 16 '07 #21

P: n/a

JohnQ wrote in message...
>
"Ian Collins" <ia******@hotmail.comwrote in message...
Apply the same rules as you apply to your classes. If you need to
initialise members on creation or copy, you need constructors.

I was pondering the technique of restricting default constructor, copy
constructor, assignment operator though and its validity for structs as
well
as classes:

class A{
A(); // disallow def construction
A(const A&); // disallow copy construction
const A& operator=(const A&); // disallow assignment
public
int data_member;
A(int arg) : data_member(arg) {}
};

struct B{
private: // to be consistant with the class A
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment
public:
int data_member; // public by default

B(int arg) : data_member( arg ){}
};

If I disallow the stuff in struct B, it acts less like a C struct, yes?
John
A 'C++' struct is NOT a 'C' struct. It can act like a 'C' struct if that's
the way you design it.

With the 'private:' and 'public:' I added to 'B', 'A' and 'B' are the same.
Try using 'A' and 'B', then swap the 'class' and 'struct', try it again. Can
you see any difference?

You can even do:

struct AA{ virtual ~AA(){} };
class BB : public AA{/*stuff*/};
BB bb;

class CC{ public: virtual ~CC(){} };
struct DD : public CC{/*stuff*/};
DD dd;

Use 'public/private/protected' for inheritance as needed, as well as inside
the class/struct.

Try it!

--
Bob R
POVrookie
Jun 16 '07 #22

P: n/a

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:Oe******************************@comcast.com. ..
JohnQ wrote:
>[..]
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

int data_member; // public by default

B(int arg)
: data_member(arg) {}
};

If I disallow the stuff in struct B, it acts less like a C struct,
yes?

As soon as you add a c-tor to B, it stops being a POD. Whether you
"disallow the stuff" or not does not matter after that, it's not
"a C struct" any more.
But for all practical purposes, it acts like one?

John

Jun 17 '07 #23

P: n/a
JohnQ wrote:
>
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:Oe******************************@comcast.com. ..
>JohnQ wrote:
>>[..]
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

int data_member; // public by default

B(int arg)
: data_member(arg) {}
};

If I disallow the stuff in struct B, it acts less like a C struct,
yes?

As soon as you add a c-tor to B, it stops being a POD. Whether you
"disallow the stuff" or not does not matter after that, it's not
"a C struct" any more.

But for all practical purposes, it acts like one?
No, it does not. You have added a constructor. Compare

struct X {
int x;
};

X x = {2};

and

struct Y {
int x;
Y() {}
};

Y y = {2};

--
Ian Collins.
Jun 17 '07 #24

P: n/a

"BobR" <re***********@worldnet.att.netwrote in message
news:2l********************@bgtnsc04-news.ops.worldnet.att.net...
>
JohnQ wrote in message...
>>
"Ian Collins" <ia******@hotmail.comwrote in message...
Apply the same rules as you apply to your classes. If you need to
initialise members on creation or copy, you need constructors.

I was pondering the technique of restricting default constructor, copy
constructor, assignment operator though and its validity for structs as
well
>as classes:

class A{
A(); // disallow def construction
A(const A&); // disallow copy construction
const A& operator=(const A&); // disallow assignment
public
int data_member;
A(int arg) : data_member(arg) {}
};

struct B{

private: // to be consistant with the class A
> B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

public:
> int data_member; // public by default

B(int arg) : data_member( arg ){}
};

If I disallow the stuff in struct B, it acts less like a C struct, yes?
John

A 'C++' struct is NOT a 'C' struct.
I'm trying to figure out when/if I can rely on a C++ to be "C-struct-like".
(Else I'll use the wrapper style I also posted... which may be easier than
trying to figure out what goes on behind the scenes).
It can act like a 'C' struct if that's the way you design it.
I thought all the above thingsare like a C struct. I'm just "worried" about
the layout and size for bitwise copying and such.
With the 'private:' and 'public:' I added to 'B', 'A' and 'B' are the
same.
I realize that. But you made struct B "class-like". I'd like some ensurance
the other way: making classes struct-like (or rather, knowing when they are
such).
Try using 'A' and 'B', then swap the 'class' and 'struct', try it again.
Can
you see any difference?
Of course not, i wouldn't expect to.
>
You can even do:

struct AA{ virtual ~AA(){} };
class BB : public AA{/*stuff*/};
BB bb;

class CC{ public: virtual ~CC(){} };
struct DD : public CC{/*stuff*/};
DD dd;

Use 'public/private/protected' for inheritance as needed, as well as
inside
the class/struct.

Try it!
Why? It's not what I'm concerned about. I'm "worried" about what the thing
looks like in memory, not elementary access specifier stuff (unless it
affects the layout making it different that a struct).

John

Jun 17 '07 #25

P: n/a

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:Co******************************@comcast.com. ..
JohnQ wrote:
>"Victor Bazarov" <v.********@comAcast.netwrote in message
news:gu******************************@comcast.com ...
>>JohnQ wrote:
Are a default constructor, destructor, copy constructor and
assignment operator generated by the compiler for a struct if they
are not explicitely defined?

If by a struct you mean POD, then yes, but only conceptually.

Different from an identical class?

What's "an identical class"? A class with the same order of its
members, all declared public? No difference.
I'm concerned about blasting it around like a C struct. That and keeping the
size the same.
>Conceptually how?

Conceptually, every type has a destructor (or you can say that it
does, since you can call it). The standard has s concept of
"a pseudo-destructor call", which means that any type has at least
a pseudo-destructor. In my book you can say that a concept of
a destructor exists for every type.
Understood. That's what the constructor/copy constructor/assignment
operator/destructor do as together: make classes (or structs) behave like
built-in types.
There is no code where the
CPU is led to perform some actions when an object of a POD type is
disposed of, yes. In that sense, a POD type does not have a d-tor.
So, conceptually, yes, physically, no.
See, now I think someone else said that those things would be generated
(maybe they didn't). I had a feeling they weren't. So that's saying
restricting those things in structs is unnecessary.

Hmmm... now if a class is defined just like a struct but has the class'
keyword, will the <whatever you call that group of functionsbe generated
always?
>
>>If by a struct you mean any class where you only specify data
members, then it depends on the data members.

Lately, I've been pondering, "when does a struct stop being a
struct?". To me, that's when its not the same size as a C struct or
not layed out the same. So obviously, when a virtual function gets
added, then "a struct stops being a struct". I think I can add
non-virtual member functions, non-virtual destructor and operators ad
infinitum and the "struct will still be a struct" (right?).

Nope. If we agree to substitute the words "C struct" with "POD",
then the Standard says that as soon as you add a user-defined c-tor,
it's not a POD any more, so not all non-virtual member functions
are "harmless" as far as POD-ness is concerned.
So I lose all guarantees about the layout and size of thing (it's
implemenation-specific what the thing looks like in memory?)?
>
>Even
though some explicit syntax would make things more evident:

struct A
{
int data;
};

struct B
{
int data;

B(int val){ data = val; } // OK, not virtual
};

Here, 'B' is not a POD class.
OK. So, don't use it like a C struct ever?
>
>class StructWrapper
{
A a_struct;

public:
A(int val){ a_struct.data = val; }

You mean

StructWrapper(int val) { a_struct.data = val; }

, right?
Yes.
>
> operator A&(){ return a_struct; }
};

Where struct B can be used identically to struct A or StructWrapper (I
hope!) as the layouts and sizes are the same (assume the operator is
being used for StructWrapper when I say "can be used identically").

Nothing in the Standard says what the layouts are. We cannot rely on
their being the same.
You see what I'm trying to indicate though right? That I want to be able to
memcpy these things and the like, based upon their size.
>
>sizeof(A)==sizeof(B)==sizeof(StructWrapper)

That doesn't matter.
It was actually a question. And when it deviates from that. The moment I
use 'private' in a struct, all bets are off? Meaning there could be
something tucked between the start of the object in memory and the first
data member?
>
>But a_struct in StructWrapper would have to be made public to
guarantee the same layout as A and B?

Again, there is no way to "guarantee" what's not defined. There is
no definition of a complete class layout in the Standard.
What about a struct with constructor?
What about a struct with just POD data members?
>
>>
>>>I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification"
(and a few minor other things). When I create a class, I always
start by declaring the default constructor, copy constructor and
assignment operator private with no implementation. I don't do that
for structs though (I consider structs like they were in C, but
they really are not in the implementation as far as I know). I'm
thinking that I don't handle structs the same because I trust the
compiler to do the right thing in the case of structs whereas
bitwise copy for a class may not be what is desired, for example.

What's "bitwise copy"? I don't know of that concept in C++.

The equivalent of doing a memcpy of the class or struct (whether I
used the right terminology or not I don't know... "bytewise" seems
more appropriate).

Well, calling 'memcpy' upon copy-constructing an object is up to the
implementation. There is no way to know exactly what they do with
POD, most likely 'memcpy', or 'memmove', or some such. However, it
would be safer to assume that "memberwise copy" is performed, which
means that copy semantics for each member (provided they exist) are
invoked.
OK. Someone else said that memberwise copy was done.
>
>>>Is the above reasoning OK? Should I continue NOT declaring/defining
the default stuff for structs?

It's up to you. And the ability of the compiler to generate the
functions you don't declare/define depends on the data members.

OK, so from what I gather, the compiler may or may not generate the
functions/operators depending on the data members. Is it that if
there is any non-POD data member, then the functions/operators get
generated? Is it always the full set (?): default constructor, copy
constructor, assignment operator, (destructor?).

No, not always. For example, it's possible to copy-construct
a reference, but it's not possible to assign one, so if your class
has a data member that is a reference (it does make it non-POD, BTW),
then the copy c-tor can (and will) be generated but the copy
assignment op cannot (and will not) be.
That's getting away from "struct with only POD data members", and that is
what I'm really only concerned with.

John

Jun 17 '07 #26

P: n/a

"Ian Collins" <ia******@hotmail.comwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
>>
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:Oe******************************@comcast.com ...
>>JohnQ wrote:
[..]
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment

int data_member; // public by default

B(int arg)
: data_member(arg) {}
};

If I disallow the stuff in struct B, it acts less like a C struct,
yes?

As soon as you add a c-tor to B, it stops being a POD. Whether you
"disallow the stuff" or not does not matter after that, it's not
"a C struct" any more.

But for all practical purposes, it acts like one?
No, it does not. You have added a constructor.
I meant in memory. I still have the same question as when I started I guess:
"when does a struct stop being a struct?". And by that, I mean the
guarantees I have for using it in a memcpy call for example.

struct A
{
int val;
};

class B
{
int val;

B(int x){ val = x; }
};

Is the following always trouble (?):

memcpy(&A, &B, sizeof(A));
>Compare

struct X {
int x;
};

X x = {2};

and

struct Y {
int x;
Y() {}
};

Y y = {2};
Yeah, but that's my issue (I know I didn't state it very directly probably).
I'm not really worried about the behavioural diffences.

John

Jun 17 '07 #27

P: n/a
JohnQ wrote:
>
I'm trying to figure out when/if I can rely on a C++ to be
"C-struct-like".
It has been clearly explained elsethread.

If you want a struct to act like a C struct, use a struct that's legal C.

Or are you just being obtuse?

--
Ian Collins.
Jun 17 '07 #28

P: n/a

"Ian Collins" <ia******@hotmail.comwrote in message
news:5d**************@mid.individual.net...
JohnQ wrote:
>>
I'm trying to figure out when/if I can rely on a C++ to be
"C-struct-like".

It has been clearly explained elsethread.

If you want a struct to act like a C struct, use a struct that's legal C.

Or are you just being obtuse?
:P

I'm still not sure "when I can get away with it" though. I was kind of under
the impression that I could "get away with it". Perhaps not. Maybe
jettisoning C roots is not possible nor desireable.

John

Jun 17 '07 #29

P: n/a
On 2007-06-16 21:11:39 -0700, "JohnQ"
<jo***********************@yahoo.comsaid:
>
"Ian Collins" <ia******@hotmail.comwrote in message
news:5d**************@mid.individual.net...
>JohnQ wrote:
>>>
I'm trying to figure out when/if I can rely on a C++ to be
"C-struct-like".

It has been clearly explained elsethread.

If you want a struct to act like a C struct, use a struct that's legal C.

Or are you just being obtuse?

:P

I'm still not sure "when I can get away with it" though. I was kind of
under the impression that I could "get away with it". Perhaps not.
Maybe jettisoning C roots is not possible nor desireable.
What are you not sure about? As Ian just said, essentially, if you
write a struct that would be legal in both C and C++, then it will
behave just like a C struct. That is when you can "get away with it".

--
Clark S. Cox III
cl*******@gmail.com

Jun 17 '07 #30

P: n/a

"Clark Cox" <cl*******@gmail.comwrote in message
news:2007061621264816807-clarkcox3@gmailcom...
On 2007-06-16 21:11:39 -0700, "JohnQ"
<jo***********************@yahoo.comsaid:
>>
"Ian Collins" <ia******@hotmail.comwrote in message
news:5d**************@mid.individual.net...
>>JohnQ wrote:

I'm trying to figure out when/if I can rely on a C++ to be
"C-struct-like".

It has been clearly explained elsethread.

If you want a struct to act like a C struct, use a struct that's legal
C.

Or are you just being obtuse?

:P

I'm still not sure "when I can get away with it" though. I was kind of
under the impression that I could "get away with it". Perhaps not. Maybe
jettisoning C roots is not possible nor desireable.

What are you not sure about? As Ian just said, essentially, if you write a
struct that would be legal in both C and C++, then it will behave just
like a C struct. That is when you can "get away with it".
So my StructWrapper class is my avenue to program like I want to (in that
pattern)?

John

Jun 17 '07 #31

P: n/a
JohnQ wrote:
:: "Victor Bazarov" <v.********@comAcast.netwrote in message

::: Conceptually, every type has a destructor (or you can say that it
::: does, since you can call it). The standard has s concept of
::: "a pseudo-destructor call", which means that any type has at least
::: a pseudo-destructor. In my book you can say that a concept of
::: a destructor exists for every type.
::
:: Understood. That's what the constructor/copy constructor/assignment
:: operator/destructor do as together: make classes (or structs)
:: behave like built-in types.
::
::: There is no code where the
::: CPU is led to perform some actions when an object of a POD type is
::: disposed of, yes. In that sense, a POD type does not have a
::: d-tor. So, conceptually, yes, physically, no.
::
:: See, now I think someone else said that those things would be
:: generated (maybe they didn't). I had a feeling they weren't. So
:: that's saying restricting those things in structs is unnecessary.

What Victor means with "conceptually" is that the destructor for a POD
doesn't have to do anything. If you look at the machine code generated
by the compiler, you will not find anything.

Does that mean that it is not there, or just that the compiler inlined
an empty function? :-)

:: Hmmm... now if a class is defined just like a struct but has the
:: class' keyword, will the <whatever you call that group of
:: functionsbe generated always?
::

A class and a struct is the same, except for the need (or non-need) of
the keyword public.
:::: OK, so from what I gather, the compiler may or may not generate
:::: the functions/operators depending on the data members. Is it
:::: that if there is any non-POD data member, then the
:::: functions/operators get generated? Is it always the full set
:::: (?): default constructor, copy constructor, assignment operator,
:::: (destructor?).
:::
::: No, not always. For example, it's possible to copy-construct
::: a reference, but it's not possible to assign one, so if your class
::: has a data member that is a reference (it does make it non-POD,
::: BTW), then the copy c-tor can (and will) be generated but the copy
::: assignment op cannot (and will not) be.
::
:: That's getting away from "struct with only POD data members", and
:: that is what I'm really only concerned with.

But this is important. One of the basic requirements of a POD is that
it can only have POD members.

What doesn't matter is if you call it a struct or a class.
Bo Persson
Jun 17 '07 #32

P: n/a
JohnQ wrote:
::
:: I meant in memory. I still have the same question as when I
:: started I guess: "when does a struct stop being a struct?".

I think this is you basic problem! The standard says that certain
structures are PODs. Everything else is not.

8.5.1 Aggregates
"An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3)."

9 Classes
"A POD-struct is an aggregate class that has no non-static data
members of type non-POD-struct, non-POD-union (or array of such types)
or reference, and has no user-defined copy assignment operator and no
user defined destructor."

If you fullfill ALL the requirements, you are a POD. If you miss only
one, you are not.
:: And by
:: that, I mean the guarantees I have for using it in a memcpy call
:: for example.
::
:: struct A
:: {
:: int val;
:: };
::
:: class B
:: {
:: int val;
::
:: B(int x){ val = x; }
:: };
::
:: Is the following always trouble (?):
::
:: memcpy(&A, &B, sizeof(A));
::

It is trouble in that the standard doesn't guarantee that it should
work. It just might anyway, but we don't know.

We cannot test it either, because the standard just doesn't say what
should happen. So different things could happen different times, or
with different compiler options, or definitely with different
compilers.
Bo Persson
Jun 17 '07 #33

P: n/a
JohnQ wrote:
:: "Gavin Deane" <de*********@hotmail.comwrote in message

::: Perhaps, but it's not defined in C++. Of more direct relevance to
::: the OP though is that, regardless of whether we're all happy with
::: that definition of "bitwise copy", it's not what happens in the
::: implicitly- defined copy constructor, which does a memberwise
::: copy.
::
:: That's interesting. Apparently "a struct is a struct" hardly ever!
:: Oh wait, does C do memberwise copy of structs also or bitwise?

In C there is not much of a difference!

Here's something else:

In C and C++, the *compiler* is allowed to do a bitwise copy whenever
it knows that it will work (and is better in some way). This means
that the compiler generated copy constructor and assignment operator
might look like a memcpy (or better!), even for a non-POD class.

It is just you, the programmer, that cannot do this, because there are
no guarantees in the standard that it will work always. The compiler
knows all the special cases, and is allowed to take advantage of this
knowledge.
Bo Persson
Jun 17 '07 #34

P: n/a
On Jun 17, 3:26 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
"Ian Collins" <ian-n...@hotmail.comwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message
news:Oe******************************@comcast.com ...
JohnQ wrote:
[..]
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment
>> int data_member; // public by default
>> B(int arg)
: data_member(arg) {}
};
>>If I disallow the stuff in struct B, it acts less like a C struct,
yes?
>As soon as you add a c-tor to B, it stops being a POD. Whether you
"disallow the stuff" or not does not matter after that, it's not
"a C struct" any more.
But for all practical purposes, it acts like one?
No, it does not. You have added a constructor.
I meant in memory. I still have the same question as when I
started I guess: "when does a struct stop being a struct?".
When it's compiled with a C++ compiler? What do you mean by "a
struct", exactly? In C++, even a POD struct is a class type.
And by that, I mean the guarantees I have for using it in a
memcpy call for example.
If the class has a constructor, it can't be memcpy'ed, at least
according to the standard.
struct A
{
int val;
};
class B
{
int val;
B(int x){ val = x; }
};
Is the following always trouble (?):
memcpy(&A, &B, sizeof(A));
The standard says it is undefined behavior, although you may get
away with it.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 17 '07 #35

P: n/a
On Jun 17, 12:06 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
JohnQ wrote:
"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message
news:gu******************************@comcast.com. ..
JohnQ wrote:
Are a default constructor, destructor, copy constructor and
assignment operator generated by the compiler for a struct if they
are not explicitely defined?
If by a struct you mean POD, then yes, but only conceptually.
Different from an identical class?
What's "an identical class"? A class with the same order of its
members, all declared public? No difference.
Actually, the standard has a definition for "an identical
class". It's called the "one definition rule". But I rather
doubt that this is what JohnQ is talking about. (Of course, I'm
not too sure what he's talking about. He seems to avoid precise
vocabulary intentionally, just to create confusion.)

Anyway, someone else has already posted the definition of POD,
which is about the only real categorization which is recognized
by the standard. (And I know you know that.)
Conceptually how?
Conceptually, every type has a destructor (or you can say that it
does, since you can call it). The standard has s concept of
"a pseudo-destructor call", which means that any type has at least
a pseudo-destructor. In my book you can say that a concept of
a destructor exists for every type. There is no code where the
CPU is led to perform some actions when an object of a POD type is
disposed of, yes. In that sense, a POD type does not have a d-tor.
So, conceptually, yes, physically, no.
The standard doesn't talk about "pseudo-destructors". What I
think you're getting at is that you can call the destructor for
any type, e.g. something like p->~int() is legal. (Obviously,
no one does this directly. But a lot of template code results
in it, and in pre-template days, it ended up generated by
<generic.hjust about any time you wrote a container class.)
Explicitly calling the destructor on a type such as int, which
doesn't have a destructor, is a no-op.

A second point to keep in mind is that a class type (i.e. any
type defined by means of the keywords class, struct or union)
always has a destructor. If you don't provide one, the compiler
does. However, a "trivial destructor" doesn't prevent the type
from being a POD. The standard also defines very rigorously
when a destructor is trivial; a user defined destructor is never
trivial (but the compiler generated one is not always trivial
either).
What's "bitwise copy"? I don't know of that concept in C++.
The equivalent of doing a memcpy of the class or struct (whether I
used the right terminology or not I don't know... "bytewise" seems
more appropriate).
Well, calling 'memcpy' upon copy-constructing an object is up to the
implementation. There is no way to know exactly what they do with
POD, most likely 'memcpy', or 'memmove', or some such. However, it
would be safer to assume that "memberwise copy" is performed, which
means that copy semantics for each member (provided they exist) are
invoked.
According to the standard, the semantic is always member-wise
copy. As you know, of course, the compiler can do anything it
wishes as long as the observable behavoir of the program is "as
if" memberwise copy took place. In practice, there are probably
a lot of classes (not even always POD's) in which the compiler
will effectively generate the equivalent of a memcpy, because it
can determine that doing so, instead of literally doing a
memberwise copy, will not result in any difference in the
observable behavior.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 17 '07 #36

P: n/a
On 2007-06-16 21:51:36 -0700, "JohnQ"
<jo***********************@yahoo.comsaid:
>
"Clark Cox" <cl*******@gmail.comwrote in message
news:2007061621264816807-clarkcox3@gmailcom...
>On 2007-06-16 21:11:39 -0700, "JohnQ"
<jo***********************@yahoo.comsaid:
>>>
"Ian Collins" <ia******@hotmail.comwrote in message
news:5d**************@mid.individual.net...
JohnQ wrote:
>
I'm trying to figure out when/if I can rely on a C++ to be
"C-struct-like".

It has been clearly explained elsethread.

If you want a struct to act like a C struct, use a struct that's legal C.

Or are you just being obtuse?

:P

I'm still not sure "when I can get away with it" though. I was kind of
under the impression that I could "get away with it". Perhaps not.
Maybe jettisoning C roots is not possible nor desireable.

What are you not sure about? As Ian just said, essentially, if you
write a struct that would be legal in both C and C++, then it will
behave just like a C struct. That is when you can "get away with it".

So my StructWrapper class is my avenue to program like I want to (in
that pattern)?
No. Your StructWrapper and B classes have user defined constructors;
therefore they are not POD types. There is no way to guarantee that
instances of a POD type and a non-POD type will be laid out identically
in memory.

--
Clark S. Cox III
cl*******@gmail.com

Jun 17 '07 #37

P: n/a
"JohnQ" <jo***********************@yahoo.comwrote in message
news:kC*****************@newssvr22.news.prodigy.ne t...
>
"Jim Langston" <ta*******@rocketmail.comwrote in message
news:O0*************@newsfe06.lga...
>"JohnQ" <jo***********************@yahoo.comwrote in message
news:Hy*****************@newssvr19.news.prodigy.n et...
>>Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not
explicitely defined?

I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification" (and
a
few minor other things). When I create a class, I always start by
declaring the default constructor, copy constructor and assignment
operator private with no implementation. I don't do that for structs
though (I consider structs like they were in C, but they really are not
in the implementation as far as I know). I'm thinking that I don't
handle
structs the same because I trust the compiler to do the right thing in
the case of structs whereas bitwise copy for a class may not be what is
desired, for example.

Is the above reasoning OK? Should I continue NOT declaring/defining the
default stuff for structs?

If your structure is POD, then there should be no reason not to allow the
compiler to create default constructor, destrucctor, copy constructor and
assignment operators.

That's what I was thinking. I wasn't sure if the compiler generates those
things for a POD struct. Are you sure?
The only real difference between a class and a structure is that structure
is public by default, class is private. Other than that, they act exactly
the same. So, yes, I am positive that the compiler will create the 4.
>I would say it was okay, but I do not know for exactly what reason you
crete the 4 for classes (not saying it's a bad thing, probably a very
good
thing, I just don't know your reasoning behind it).

To prevent those things from happening unknowingly for what could be a
non-POD.
Right, hence my reasoning that if you are sure it's POD then you wouldn't
need them.

Personally, I use struct for POD, class otherwise. And, yes, if I make a
structure that becomes non POD, I change it to a class.
Jun 17 '07 #38

P: n/a

"Bo Persson" <bo*@gmb.dkwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
::
:: I meant in memory. I still have the same question as when I
:: started I guess: "when does a struct stop being a struct?".

I think this is you basic problem! The standard says that certain
structures are PODs. Everything else is not.

8.5.1 Aggregates
"An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3)."

9 Classes
"A POD-struct is an aggregate class that has no non-static data members of
type non-POD-struct, non-POD-union (or array of such types) or reference,
and has no user-defined copy assignment operator and no user defined
destructor."
OK, then POD-struct = Aggregate (8.5.1) rules + aggregate class (9) rules:

1. No user-defined constructor, copy constructor, assignment operator,
destructor.
2. No virtual functions.
3. No base classes.
4. No private or protected non-static data members .
5. No non-POD data members.
6. No reference data members.

Got it. Apparently, I'll be (re)writing a lot more StructWrapper-type
classes.
>
If you fullfill ALL the requirements, you are a POD. If you miss only one,
you are not.
:: And by
:: that, I mean the guarantees I have for using it in a memcpy call
:: for example.
::
:: struct A
:: {
:: int val;
:: };
::
:: class B
:: {
:: int val;
::
:: B(int x){ val = x; }
:: };
::
:: Is the following always trouble (?):
::
:: memcpy(&A, &B, sizeof(A));
::

It is trouble in that the standard doesn't guarantee that it should work.
It just might anyway, but we don't know.
We cannot test it either, because the standard just doesn't say what
should happen. So different things could happen different times, or with
different compiler options, or definitely with different compilers.
OK. Then "bad" to do.

John

Jun 18 '07 #39

P: n/a

"James Kanze" <ja*********@gmail.comwrote in message
news:11**********************@q69g2000hsb.googlegr oups.com...
On Jun 17, 3:26 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
"Ian Collins" <ian-n...@hotmail.comwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message
news:Oe******************************@comcast.com ...
JohnQ wrote:
[..]
struct B
{
B(); // disallow def construction
B(const B&); // disallow copy construction
const B& operator=(const B&); // disallow assignment
>> int data_member; // public by default
>> B(int arg)
: data_member(arg) {}
};
>>If I disallow the stuff in struct B, it acts less like a C struct,
yes?
>As soon as you add a c-tor to B, it stops being a POD. Whether you
"disallow the stuff" or not does not matter after that, it's not
"a C struct" any more.
But for all practical purposes, it acts like one?
No, it does not. You have added a constructor.
I meant in memory. I still have the same question as when I
started I guess: "when does a struct stop being a struct?".
"When it's compiled with a C++ compiler? What do you mean by "a
struct", exactly? In C++, even a POD struct is a class type."

But apparently, the moment you add something "class-like" to the struct,
it's not a POD anymore.
And by that, I mean the guarantees I have for using it in a
memcpy call for example.
"If the class has a constructor, it can't be memcpy'ed, at least
according to the standard."

I wasn't sure about that until the posts in this thread solidified it for
me.
struct A
{
int val;
};
class B
{
int val;
B(int x){ val = x; }
};
Is the following always trouble (?):
memcpy(&A, &B, sizeof(A));
"The standard says it is undefined behavior, although you may get
away with it."

Yeah, I get it now. Bo Pearson's post made it official in my mind about POD
structs. There must be an official definition of POD somewhere also huh.
That would be nice to see.

John

Jun 18 '07 #40

P: n/a

"Clark Cox" <cl*******@gmail.comwrote in message
news:2007061707482316807-clarkcox3@gmailcom...
On 2007-06-16 21:51:36 -0700, "JohnQ"
<jo***********************@yahoo.comsaid:
>>
"Clark Cox" <cl*******@gmail.comwrote in message
news:2007061621264816807-clarkcox3@gmailcom...
>>On 2007-06-16 21:11:39 -0700, "JohnQ"
<jo***********************@yahoo.comsaid:
"Ian Collins" <ia******@hotmail.comwrote in message
news:5d**************@mid.individual.net...
JohnQ wrote:
>>
>I'm trying to figure out when/if I can rely on a C++ to be
>"C-struct-like".
>
It has been clearly explained elsethread.
>
If you want a struct to act like a C struct, use a struct that's legal
C.
>
Or are you just being obtuse?

:P

I'm still not sure "when I can get away with it" though. I was kind of
under the impression that I could "get away with it". Perhaps not.
Maybe jettisoning C roots is not possible nor desireable.

What are you not sure about? As Ian just said, essentially, if you write
a struct that would be legal in both C and C++, then it will behave just
like a C struct. That is when you can "get away with it".

So my StructWrapper class is my avenue to program like I want to (in that
pattern)?

No. Your StructWrapper and B classes have user defined constructors;
therefore they are not POD types. There is no way to guarantee that
instances of a POD type and a non-POD type will be laid out identically in
memory.
Well consider what the intention of the wrapper class is: to give anything
that wants a struct like the one the class wraps, a refence to the embedded
struct via the defined operator.

void BlastToDisk(struct A& s); // when given a StructWrapper object, i
// it gets a struct A& from
it

I didn't mean to suggest that StructWrapper could be memcpy'd and the like
just because the first data member was a struct.

John

Jun 18 '07 #41

P: n/a

"Bo Persson" <bo*@gmb.dkwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
:: "Victor Bazarov" <v.********@comAcast.netwrote in message

::: Conceptually, every type has a destructor (or you can say that it
::: does, since you can call it). The standard has s concept of
::: "a pseudo-destructor call", which means that any type has at least
::: a pseudo-destructor. In my book you can say that a concept of
::: a destructor exists for every type.
::
:: Understood. That's what the constructor/copy constructor/assignment
:: operator/destructor do as together: make classes (or structs)
:: behave like built-in types.
::
::: There is no code where the
::: CPU is led to perform some actions when an object of a POD type is
::: disposed of, yes. In that sense, a POD type does not have a
::: d-tor. So, conceptually, yes, physically, no.
::
:: See, now I think someone else said that those things would be
:: generated (maybe they didn't). I had a feeling they weren't. So
:: that's saying restricting those things in structs is unnecessary.

What Victor means with "conceptually" is that the destructor for a POD
doesn't have to do anything. If you look at the machine code generated by
the compiler, you will not find anything.

Does that mean that it is not there, or just that the compiler inlined an
empty function? :-)

:: Hmmm... now if a class is defined just like a struct but has the
:: class' keyword, will the <whatever you call that group of
:: functionsbe generated always?
::

A class and a struct is the same, except for the need (or non-need) of the
keyword public.
:::: OK, so from what I gather, the compiler may or may not generate
:::: the functions/operators depending on the data members. Is it
:::: that if there is any non-POD data member, then the
:::: functions/operators get generated? Is it always the full set
:::: (?): default constructor, copy constructor, assignment operator,
:::: (destructor?).
:::
::: No, not always. For example, it's possible to copy-construct
::: a reference, but it's not possible to assign one, so if your class
::: has a data member that is a reference (it does make it non-POD,
::: BTW), then the copy c-tor can (and will) be generated but the copy
::: assignment op cannot (and will not) be.
::
:: That's getting away from "struct with only POD data members", and
:: that is what I'm really only concerned with.

But this is important. One of the basic requirements of a POD is that it
can only have POD members.

What doesn't matter is if you call it a struct or a class.
Well since a class defaults to private access, the moment you put a data
member into it without specifying 'public', it's no longer an aggregate.
"Warning Master Robinson, your struct is no longer what you think it is!".

John

Jun 18 '07 #42

P: n/a

"James Kanze" <ja*********@gmail.comwrote in message
news:11**********************@w5g2000hsg.googlegro ups.com...
On Jun 17, 12:06 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
JohnQ wrote:
"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message
news:gu******************************@comcast.com. ..
JohnQ wrote:
Are a default constructor, destructor, copy constructor and
assignment operator generated by the compiler for a struct if they
are not explicitely defined?
If by a struct you mean POD, then yes, but only conceptually.
Different from an identical class?
What's "an identical class"? A class with the same order of its
members, all declared public? No difference.
"Actually, the standard has a definition for "an identical
class". It's called the "one definition rule". But I rather
doubt that this is what JohnQ is talking about. (Of course, I'm
not too sure what he's talking about. He seems to avoid precise
vocabulary intentionally, just to create confusion.)"

That's not true. If by "precise vocabulary" you mean terminology specificly
used in the standard, well the standard is hardly bedtime reading material
for me and not from where I learned C++ from either.

"Anyway, someone else has already posted the definition of POD,
which is about the only real categorization which is recognized
by the standard. (And I know you know that.)"

It would be nice to see the formal definition.

John

Jun 18 '07 #43

P: n/a
On Jun 19, 12:59 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:11**********************@q69g2000hsb.googlegr oups.com...
On Jun 17, 3:26 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
"Ian Collins" <ian-n...@hotmail.comwrote in message
news:5d*************@mid.individual.net...
JohnQ wrote:
>"Victor Bazarov" <v.Abaza...@comAcast.netwrote in message
>>news:Oe******************************@comcast.co m...
>>JohnQ wrote:
>>>[..]
>>>struct B
>>>{
>>> B(); // disallow def construction
>>> B(const B&); // disallow copy construction
>>> const B& operator=(const B&); // disallow assignment
>>> int data_member; // public by default
>>> B(int arg)
>>> : data_member(arg) {}
>>>};
>>>If I disallow the stuff in struct B, it acts less like a C struct,
>>>yes?
>>As soon as you add a c-tor to B, it stops being a POD. Whether you
>>"disallow the stuff" or not does not matter after that, it's not
>>"a C struct" any more.
>But for all practical purposes, it acts like one?
No, it does not. You have added a constructor.
I meant in memory. I still have the same question as when I
started I guess: "when does a struct stop being a struct?".
"When it's compiled with a C++ compiler? What do you mean by "a
struct", exactly? In C++, even a POD struct is a class type."
But apparently, the moment you add something "class-like" to the struct,
it's not a POD anymore.
No. I suspected that what you were actually talking about were
POD's, but I wanted to make it clear. C++ doesn't really have
"struct"'s, just classes, but it does distinguish between POD's
and other types. And if your problem is interfacing with a C
API, a POD struct is really what you need; it's the equivalent
of a C struct.

[...]
Yeah, I get it now. Bo Pearson's post made it official in my
mind about POD structs. There must be an official definition
of POD somewhere also huh. That would be nice to see.
I thought someone had already posted it, but from the standard:

§3.9 paragraph 11:
Arithmetic types (3.9.1), enumeration types, pointer
types, and pointer to member types (3.9.2), and
cv-qualified versions of these types (3.9.3) are
collectively called scalar types. Scalar types,
POD-struct types, POD-union types (clause 9), arrays of
such types and cv-qualified versions of these types
(3.9.3) are collectively called POD types.

§9 paragraph 4:
A POD-struct is an aggregate class that has no
non-static data members of type non-POD-struct,
non-POD-union (or array of such types) or reference, and
has no user-declared copy assignment operator and no
user-declared destructor. Similarly, a POD-union is an
aggregate union that has no non-static data members of
type non-POD-struct, non-POD-union (or array of such
types) or reference, and has no user-declared copy
assignment operator and no user-declared destructor. A
POD class is a class that is either a POD-struct or a
POD-union.

And finally, §8.5.1 paragraph 1:
An aggregate is an array or a class (clause 9) with no
user-declared constructors (12.1), no private or
protected non-static data members (clause 11), no base
classes (clause 10), and no virtual functions (10.3).

(This is from N2134, the version of the draft that I happen
to have on line here. I think that there's some open work
still in progress here, because in theory, at least, a
compiler is not required to maintain order when there is an
intervening access specifier, even when it doesn't change
access. So---again in theory---given:

class C
{
public: int x ;
public: int y ;
public: int x ;
} ;

the compiler is allowed to put x, y and z in any order, even
though this is---according to the rules above---a POD
struct.)

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 19 '07 #44

This discussion thread is closed

Replies have been disabled for this discussion.