![]() |
|
|
|
#11 |
|
In article <VV%Fm.41268$>,
says... > > Can C++0x PODs/aggregates have user-defined constructors and still be > PODs/aggregates? If not, why not? How about conversion operators? And what > is the difference between a POD and an aggregate anyway? In C++ 0x, the definition of POD no longer includes the requirement that the class be an aggregate. Instead, it introduces a couple of new terms, "standard layout class" and "trivial class". A POD has to be both. A user-defined constructor (by itself) does _not_ prevent the class from being a POD -- but you have to be really careful. In particular, a non-trivial copy constructor or non-trivial destructor _does_ prevent it from being a trivial class (IOW, copying with memcpy/memmove should work correctly). A standard layout class basically says it can't have virtual functions or virtual base classes, etc. As long as it fits both of those sets of restrictions, it's a POD. IOW, it _can_ have some "convenience ctors". Obviously I'm leaving out some of the details -- see N2960, §9/5, 9/6 for the full details. -- Later, Jerry. Jerry Coffin |
|
|
|
|
#12 |
|
Posts: n/a
|
Victor Bazarov wrote:
> dragan wrote: >> Can C++0x PODs/aggregates have user-defined constructors and still be >> PODs/aggregates? > > From [dcl.init.aggr]: > << 1 An aggregate is an array or a class (Clause 9) with no > user-provided constructors (12.1), no private or > protected non-static data members (Clause 11), no base classes (Clause > 10), and no virtual functions (10.3). >> > > So, no, once you add a user-defined c-tor, it's not an aggregate. I'm not sure what aggregates are good for. I think POD may be the key thing for layout compatibility with C and probably other languages. PODs no longer have to be aggregates in C++0x: they can have constructors, just not default or copy constructors, and no copy assignment operator. (N2690). >> How about conversion operators? > > You can have conversion operators in an aggregate (according to the > definition), if other conditions are met. I assume in a POD also. dragan |
|
|
|
#13 |
|
Posts: n/a
|
James Kanze wrote:
> The > difference between a POD and a non-POD is that a POD has > constructors and destructors which are effectively no-ops, and > an assignment operator which is the equivalent of memcpy; this > plays a role in various contexts. From N2960, I gather that a POD may not have user-defined: default constructor, copy constructor, copy assignment operator, destructor. In addition, it may not have virtual functions or virtual base classes, at most one base class and no non-static data members in the most-derived class. Other things too, but I find the aforementioned most important. So, the good news is, that seemingly a POD can have constructors other than the ones listed above and can also have a non-virtual base class. I'm not sure what "no non-static data members in the most-derived class" means exactly. The section needs more examples if you ask me. dragan |
|
|
|
#14 |
|
Posts: n/a
|
Johannes Schaub (litb) wrote:
> dragan wrote: > >> Can C++0x PODs/aggregates have user-defined constructors and still be >> PODs/aggregates? If not, why not? How about conversion operators? >> And what is the difference between a POD and an aggregate anyway? > > Aggregates but not PODs, both in C++03 and C++0x: > > string foo[10]; > struct bar { > string baz; > }; > > In C++0x, you can use memcpy on trivially copyable types. POD is too > strict a requirement for this - so if you just want to use memcpy on > a type for example, making a type trivially copyable would suffice, > in particular: > > - has no non-trivial copy constructors (12. > - has no non-trivial copy assignment operators (13.5.3, 12. > - has a trivial destructor (12.4). > > A trivial class then is a class that is trivially copyable and that > has a trivial default constructor. F is trivial and G is trivially > copyable: > > struct F { Foo() = default; F(int a):a(a) { } int a; }; > struct G { Foo(int a):a(a) { } int a; }; > > For other things, a class has to be a standard layout class. Thus is > true for "offsetof", to inspect a common initial sequence when two > such structs are in an union, etc. Look up the details in the latest > draft at 9/6. > > A POD is a class is trivial and a standard layout class and has no > members of non-POD etc... . Actually, i haven't found something in > the c++0x language in 2960 that still requires things to be PODs. > Things either seem to refer to standard layout classes or trivially > copyable. But a POD is what you want to talk with C and other languages is what I gather. dragan |
|
|
|
#15 |
|
Posts: n/a
|
Jerry Coffin wrote:
> In article <VV%Fm.41268$>, > says... >> >> Can C++0x PODs/aggregates have user-defined constructors and still be >> PODs/aggregates? If not, why not? How about conversion operators? >> And what is the difference between a POD and an aggregate anyway? > > In C++ 0x, the definition of POD no longer includes the requirement > that the class be an aggregate. Instead, it introduces a couple of > new terms, "standard layout class" and "trivial class". A POD has to > be both. A user-defined constructor (by itself) does _not_ prevent > the class from being a POD -- but you have to be really careful. In > particular, a non-trivial copy constructor or non-trivial destructor > _does_ prevent it from being a trivial class (IOW, copying with > memcpy/memmove should work correctly). > > A standard layout class basically says it can't have virtual > functions or virtual base classes, etc. > > As long as it fits both of those sets of restrictions, it's a POD. > IOW, it _can_ have some "convenience ctors". That's good news. That a POD can be derived from another class is also good news. What kind of class it can be after derived though is still unclear to me: can it have non-static data members? > > Obviously I'm leaving out some of the details -- see N2960, §9/5, 9/6 > for the full details. I downloaded N2960. I like to think in terms of the things a POD can or cannot have rather than the lingo like: trivially copyable, trivial class, standard layout, and on and on. In another post I wrote my understanding of what is and isn't allowed. dragan |
|
|
|
#16 |
|
Posts: n/a
|
On Oct 29, 11:49 pm, "dragan" <spambus...@prodigy.net> wrote:
> James Kanze wrote: > > The difference between a POD and a non-POD is that a POD has > > constructors and destructors which are effectively no-ops, > > and an assignment operator which is the equivalent of > > memcpy; this plays a role in various contexts. > From N2960, Note that N2960 is not the standard, but a draft for the next version of the standard. In particular, it differs signficantly from the current standard here (in wording---not in effect). > I gather that a POD may not have user-defined: > default constructor, copy constructor, copy assignment > operator, destructor. In addition, it may not have virtual > functions or virtual base classes, at most one base class and > no non-static data members in the most-derived class. Other > things too, but I find the aforementioned most important. The current standard simply says that a POD must be an aggregate; some of these requirements are part of being an aggregate. But you're formulating it backwards. In order to be a POD, a class must have a trivial default constructor, a trivial copy constructor, a trivial copy assignment operator and a trivial destructor. If any of these is user defined, then it is by definition non-trivial, but there are other ways for them to be non-trivial or absent: a class with a deleted copy constructor, for example (in the draft). > So, the good news is, that seemingly a POD can have > constructors other than the ones listed above If you provide any constructor, the compiler no longer provides the trivial default constructor---either you provide one (which will be non-trivial), or there isn't one. Either way, the class won't be a POD. (Or... I think you can tell the compiler to provide one explicitly, and that might be trivial.) > and can also have a non-virtual base class. Yes, but either the base class or the class itself must be empty, which sort of makes this provision useless. > I'm not sure what "no non-static data members in the > most-derived class" means exactly. The section needs more > examples if you ask me. It seems clear enough to me. Given a hierarchy (which may consist of only a single class), there may be at most one class in that hierarchy which has non-static data members---non-static, because static data members don't affect the layout in any way. I think the original formulation was clearer, and the original rules allowed an informal simplification: a POD is something you could write in C. I'm not sure what we really gain by allowing anything else. I understand the desire of separating "layout compatibility" from POD-ness, since they affect different operations (communication with other languages, memcpy-ability), but in practice, I don't think it makes any difference. -- James Kanze James Kanze |
|
|
|
#17 |
|
Posts: n/a
|
On Oct 29, 11:40 pm, "dragan" <spambus...@prodigy.net> wrote:
> Victor Bazarov wrote: > > dragan wrote: > >> Can C++0x PODs/aggregates have user-defined constructors > >> and still be PODs/aggregates? > > From [dcl.init.aggr]: > > << 1 An aggregate is an array or a class (Clause 9) with no > > user-provided constructors (12.1), no private or > > protected non-static data members (Clause 11), no base classes (Clause > > 10), and no virtual functions (10.3). >> > > So, no, once you add a user-defined c-tor, it's not an > > aggregate. > I'm not sure what aggregates are good for. Initialization syntax. The most important use is for arrays, since you can let the compiler count the members when using aggregate initialization, e.g.: std::string const names[] = { "Abert", "Bertha", "Charles" ... } ; It's also useful for structs, however, when you need static initialization (especially for tables of structs), e.g.: struct MapInit { char const* key; int value; }; MapInit const initTable[] = { { "toto", 42 }, { "titi", 0 }, // ... }; > I think POD may be the key thing for layout compatibility with > C and probably other languages. PODs no longer have to be > aggregates in C++0x: they can have constructors, just not > default or copy constructors, and no copy assignment operator. > (N2690). Layout compatibility is an awkward problem. C++ can mandate a certain number of things with regards to how the C++ compiler lays out data, but it can't mandate anything with regards to how other languages layout data. In the end, it's a lot like the ``extern "C"'' fiasco: C++ requires a compiler to support it, stating that functions declared ``extern "C"'' must be callable from C (or something along those lines). Which is all nice and fine, but what does it mean if the platform doesn't have a C compiler? Or if it has several C compilers, with different calling conventions? In practice, of course, on most small and medium sized systems today, the system ABI is defined in terms of C, which means that there will be a C compiler, and all C compilers will use a commun layout and common calling conventions, so the problem doesn't come up; C is the lowest common denominator. If you look at it closely, you'll see that the standard doesn't actually give any guarantees with regards to standard layout and other languages, for the reason stated above. There may be some advanced programming techniques which depend on standard layout, but for the everyday user, the only really significant distinction is whether the class could be written in C or not---if it could, it will be accessible from C, and probably from most other languages as well (on typical small and medium general purpose computers---I wouldn't count on it on mainframes, nor for that matter on embedded systems); otherwise, it won't be. (You may, of course, add non-virtual member functions, including conversion operators, but not constructors, destructors or assignment operators, without causing problems.) The other thing that is often important is whether the class is an aggregate which supports static initialization. But in practice, the two overlap; there are very few cases where you can use static aggregate initialization but couldn't write the class in C. (The presence of a pointer to member in the class would be an example of one.) > >> How about conversion operators? > > You can have conversion operators in an aggregate (according > > to the definition), if other conditions are met. > I assume in a POD also. A conversion operator is just an ordinary member function. -- James Kanze James Kanze |
|
|
|
#18 |
|
Posts: n/a
|
On Oct 29, 4:23 pm, Jerry Coffin <jerryvcof...@yahoo.com> wrote:
> In article <VV%Fm.41268$EU5.38...@newsfe05.iad>, > spambus...@prodigy.net says... > > Can C++0x PODs/aggregates have user-defined constructors and > > still be PODs/aggregates? If not, why not? How about > > conversion operators? And what is the difference between a > > POD and an aggregate anyway? > In C++ 0x, the definition of POD no longer includes the > requirement that the class be an aggregate. Instead, it > introduces a couple of new terms, "standard layout class" and > "trivial class". A POD has to be both. A user-defined > constructor (by itself) does _not_ prevent the class from > being a POD -- but you have to be really careful. In > particular, a non-trivial copy constructor or non-trivial > destructor _does_ prevent it from being a trivial class (IOW, > copying with memcpy/memmove should work correctly). Attention: the requirement isn't that the class not have a non-trivial X; it is that it have a trivial X. Thus, for example: struct S { S( int ); int i; }; doesn't have a non-trivial default constructor, but it doesn't have a trivial one either, and thus, is not a POD. IIUC, in the next version of the standard, you will be able to write: struct S { S( int ); S() = default; int i; }; and it will have the required trivial default constructor. > A standard layout class basically says it can't have virtual > functions or virtual base classes, etc. > As long as it fits both of those sets of restrictions, it's a > POD. IOW, it _can_ have some "convenience ctors". But IIUC, only if you ensure that it also has a trivial default constructor. Which it won't have be default if you've provided any other constructor. -- James Kanze James Kanze |
|
|
|
#19 |
|
Posts: n/a
|
On Oct 29, 11:56 pm, "dragan" <spambus...@prodigy.net> wrote:
> Jerry Coffin wrote: > That's good news. That a POD can be derived from another class > is also good news. What kind of class it can be after derived > though is still unclear to me: can it have non-static data > members? Only if it's empty itself. > > Obviously I'm leaving out some of the details -- see N2960, > > §9/5, 9/6 for the full details. > I downloaded N2960. I like to think in terms of the things a > POD can or cannot have rather than the lingo like: trivially > copyable, trivial class, standard layout, and on and on. In > another post I wrote my understanding of what is and isn't > allowed. The problem is that you can't express the requirements in terms of can or cannot have. At least partially, you have to express them in terms of "must have": a POD must have a trivial default constructor, for example (which is not the same thing as not having a non-trivial default constructor---you have three possibilities: no default constructor, trivial default constructor and non-trivial default constructor). -- James Kanze James Kanze |
|
|
|
#20 |
|
Posts: n/a
|
James Kanze wrote:
> On Oct 29, 11:49 pm, "dragan" <spambus...@prodigy.net> wrote: >> James Kanze wrote: >>> The difference between a POD and a non-POD is that a POD has >>> constructors and destructors which are effectively no-ops, >>> and an assignment operator which is the equivalent of >>> memcpy; this plays a role in various contexts. > >> From N2960, > > Note that N2960 is not the standard, but a draft for the next > version of the standard. I know. > In particular, it differs signficantly > from the current standard here (in wording---not in effect). Where is "here"? I thought that N2960 was pretty close to the "current state of the art" given that it has a date of October 25, 2009 on it. Prior to downloading N2960, I had N2800, so surely I'm a lot closer to the final standard than I was. > >> I gather that a POD may not have user-defined: >> default constructor, copy constructor, copy assignment >> operator, destructor. In addition, it may not have virtual >> functions or virtual base classes, at most one base class and >> no non-static data members in the most-derived class. Other >> things too, but I find the aforementioned most important. > > The current standard simply says that a POD must be an > aggregate; some of these requirements are part of being an > aggregate. OK, I see the disconnect now: You are talking about the current standard and I asked about C++0x. The current standard does not concern me. Wasn't the current one instituted in 2003? > > But you're formulating it backwards. In order to be a POD, a > class must have a trivial default constructor, a trivial copy > constructor, a trivial copy assignment operator and a trivial > destructor. If any of these is user defined, then it is by > definition non-trivial, That's why I said it couldn't have those as a practicality and for most purposes it was "correct enough". I'm just trying to understand it, not quote it. > but there are other ways for them to be > non-trivial or absent: a class with a deleted copy constructor, > for example (in the draft). I kinda/sorta knew that. Someone told me that before. That when I make a default constructor private so that default construction is not possible, that all bets are off for it being a POD (?). > >> So, the good news is, that seemingly a POD can have >> constructors other than the ones listed above > > If you provide any constructor, the compiler no longer provides > the trivial default constructor---either you provide one (which > will be non-trivial), or there isn't one. Either way, the class > won't be a POD. In the current standard or the draft? I was under the impression (and so is at least one other poster in this thread) that PODs can have "convenience constructors", as he put it. > (Or... I think you can tell the compiler to > provide one explicitly, and that might be trivial.) And how can someone do that? > >> and can also have a non-virtual base class. > > Yes, but either the base class or the class itself must be > empty, which sort of makes this provision useless. Indeed it would make it useless! I didn't get that information from reading the draft. Is it there or did I just skim over it I wonder. > >> I'm not sure what "no non-static data members in the >> most-derived class" means exactly. The section needs more >> examples if you ask me. > > It seems clear enough to me. Given a hierarchy (which may > consist of only a single class), there may be at most one class > in that hierarchy which has non-static data > members---non-static, because static data members don't affect > the layout in any way. It just seems weird, probably for lack of my knowledge of the intricacies/subtleties. An example would be worth a thousand words. Someone should pen "a roadmap to the C++ standard, with examples" book. Note that some "open" softwares have their licenses expressed also in layman's terms, something I have found not only useful, but interesting. > > I think the original formulation was clearer, and the original > rules allowed an informal simplification: a POD is something you > could write in C. Yes! That's really my concern: where C ends and C++ starts. > I'm not sure what we really gain by allowing > anything else. I understand the desire of separating "layout > compatibility" from POD-ness, since they affect different > operations (communication with other languages, memcpy-ability), > but in practice, I don't think it makes any difference. Nor I, for I thought they were the same thing! When I started this thread, I included "aggregate" in my quest to understand. Then I felt that POD was what I was really after. Live and learn! Now I think you just told me that "layout compatibility" is the thing and that makes "POD" nebulous! Errrrgh! dragan |
|