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 43 3729
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
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.
"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).
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
"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.
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
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
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
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
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
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
"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
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
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
"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
"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
"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
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.
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
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
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
"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
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.
"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
"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
"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
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.
"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
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
"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
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
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
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
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
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
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
"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.
"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
"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
"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
"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
"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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Peter Oliphant |
last post by:
I've been told that value structs can have default constructors (I'm using
VS C++.NET 2005 PRO using clr:/pure syntax). But the following code
generates the following error:
value struct...
|
by: Zytan |
last post by:
I have a struct constructor to initialize all of my private (or public
readonly) fields. There still exists the default constructor that sets
them all to zero. Is there a way to remove the...
|
by: RainBow |
last post by:
I understand that a compiler synthesises a default constructor if none
is provided by the user ( of course depending on the situation if
synthesis of such c'tor is actually needed in the program...
|
by: subramanian100in |
last post by:
If we provide any ctor for a class the compiler does not supply the
default ctor.
However if we do not provide the copy ctor but provide any other ctor,
the compiler still supplies the copy ctor....
|
by: puzzlecracker |
last post by:
From my understanding, if you declare any sort of constructors,
(excluding copy ctor), the default will not be included by default. Is
this correct?
class Foo{
public:
Foo(int); // no...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: Mushico |
last post by:
How to calculate date of retirement from date of birth
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: Aliciasmith |
last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM)
Please note that the UK and Europe revert to winter time on...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: isladogs |
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...
| | |