Topic: POD's (was: Proposals for small vectors?)
Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Thu, 22 Aug 2002 19:01:35 GMT Raw View
On 19 Aug 2002 18:00:12 GMT, Andrew Koenig <ark@research.att.com>
wrote:
>Natale> Do exist any real compiler who change the memory layout of a
>Natale> class only because a user defined constructor exist ?
>
>It's not a question of the memory layout; it's a question of the
>meaning of the memory. Once the class has a constructor, there is
>no reason to believe that copying an object of that class is
>equivalent to copying its memory.
So the real problem seem to be the presence of a non trivial copy
constructor, what if my class do have others non trivial constructors
but use the default compiler generated copy constructor ?
Regards,
Natale Fietta
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Daniel Miller <daniel.miller@tellabs.com>
Date: Thu, 22 Aug 2002 20:44:32 GMT Raw View
Uwe Schnitker wrote:
> "David Abrahams" <david.abrahams@rcn.com> wrote in message news:<ajut6f$3ek$1@bob.news.rcn.net>...
>
>>"Uwe Schnitker" <schnitker@sigma-c.com> wrote in message
>>news:aec458c5.0208192300.4812e81d@posting.google.com...
>>
>>>Andrew Koenig <ark@research.att.com> wrote in message
>>>
>> news:<yu99it27geu3.fsf@europa.research.att.com>...
>>
>>>>Natale> Do exist any real compiler who change the memory layout of a
>>>>Natale> class only because a user defined constructor exist ?
>>>>
>>>>It's not a question of the memory layout; it's a question of the
>>>>meaning of the memory.
>>>>
>>>Not neccessarily. The starting point of the discussion was the question
>>>wether one can pass an array or std::vector of objects (small vectors)
>>>to a C-API. This depends essentially on the memory layout being the
>>>same for C and C++.
>>>
>>>
>>
>>FYI:
>>
>>http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1356.html
>>
>>
>>-Dave
>>
>
> Thanks a lot. I really enjoyed your concise - and, hopefully, convincing -
> way to present the problem.
>
> Some comments:
>
> You don't mention a different, but closely related issue: Copying of memory
> vs. copying of objects. The main reason for the inequivalency of them is,
> AFAIK, that some internal or external data might not be adjusted as neccessary.
> This is today only guaranteed not to happen for POD's.
>
> Allowing "memcopying" for suitable non-POD's would enable some optimizations.
> (It might also make it easier to interoperate with systems or languages which
> use non-conservative garbage collections - I'm shooting from the hip here.)
>
> Note that the neccessary constraints are stronger than those for layout-
> predictabillity. A class which contains a pointer and manages it according
> to the "rule of three" could still have a predictable layout, but memcopying
> it might be disastrous, e.g. if the class manages a reference count.
>
> Similar considerations apply to "constructing" an object externally, e.g.
> allocating the momory and setting the data members of a struct in C and
> use a pointer to it as a pointer to the corresponding C++ class/struct.
> (One might call this "green-carding" the object. And no, I don't know if
> this might be important.)
>
> Possible new rules:
> 1)If a class or its members or bases have virtual functions or virtual bases,
> its memory layout is implementation-dependent and objects of it may not be
> memcopied or "green-carded".
> 2)Else if a class or its members or bases define at least one of the "famous
> three", the class cannot be memcopied or "green-carded", but its memory
> layout is predictable.
> 3)Else if a class or its members or bases define constructors (but not
> copy constructors), the class can be memcopied or "green-carded" and
> its memory layout is predictable.
> 4)Else the class is a true POD.
>
> This rules would follow a "Only grant to compiler writers what they absolutely
> need" principle. (Since I will probably never write on a C++ compiler I can
> live with that ;-).)
I applaud the recognition here that there are multiple categories of being
binary-compatible with interaction between computer languages on the same
platform and/or between platforms. When discussing binary-compatibility, I
usually summarize layout-compatibility categories as:
1) MASTER-APPRENTICE FULLY-READ COMPATIBLE (both sides agree on layout and
read semantics, but perhaps no other details) This is what people want a
substantial percentage of the time (maybe not the majority of cases of desired
binary-compatibility, but certainly not a rare case either). The master is the
sole initializer of the data. The apprentice knows how to read this data (as
const) without changing it.
2) MASTER-APPRENTICE FULLY-READ PARTIALLY-WRITE COMPATIBLE (same as
fully-read compatible, plus the receiving side knows that if it plays by a
special set of rules that it can write some bytes here and write some bytes
there safely too) The master is the sole initializer of the data. The
apprentice side is the tweaker/updater of certain master-initialized data.
3) MASTER-APPRENTICE FULLY-READ FULLY-COPY COMPATIBLE (same as
full-read/partial-write compatible plus the apprentice side has the ability to
copy data which has been already initialized by the master [i.e., mimick the
master's wisdom]) The master is the sole initializer of the data. The
apprentice may copy the master's admirable work, but the apprentice is not
allowed to initialize new data himself.
4) EQUAL-PEER FULLY-READ FULLY-WRITE COMPATIBLE (both sides recognize congruent sets of interfaces, layout, and behaviors---e.g., both langauges recognize & respect each other's constructors, pad bytes, size of types, and so forth) This is the "only in your dreams" category unless one resorts to one of object broker or data marshalling technologies as a lingua franca.
Thus I applaud both David Abraham's and Uwe Schnitker's viewpoints which
provided a multi-categorized set of expectations for a POD versus an
enhanced-POD or a 4-branch if-else set of rules. In reality (outside of
standardese) there is not merely one true C++98-esque definition of POD, but
rather at least 2 in David Abraham's POD/enhanced-POD scheme and at least 4 in
Uwe Schnitker's & Dan'l Miller's schemes. (I am unclear whether the set of 4
categories in Uwe Schnitker's scheme and the set of 4 categories in Dan'l
Miller's scheme are exactly congruent because I am unfamiliar with the verb
"green-card" [but rather only with the noun "green-card" in the USA's
Immigration & Naturalization Service context of permanent resident prior to full
citizenship].)
> BTW: Note that the "aggregate" definition is automatically satisfied in
> case 4), but not in cases 2) and 3) - neither in your "Extended POD" case.
Conversely, I find the whole topic of rule-based it-has-this
it-doesn't-have-that definition of POD (or enhanced-POD or
copyable/"greencard"able POD) at best a contrived hack and at worst combustible
fuel for endless debate & confusion & argument (as it is already today in C++98).
If certain interest groups wish to address the binary-compatibility problem at all in C++0x, then I request that C++0x take a more-disciplined less-hack'nstance approach.
First, regarding binary-compability, one must specifically itemize *with
what* one desires compatibility. One cannot be merely "compatible"; one can
only be "compatible *with*" something. The categorization of possible answers
of *with what* C++0x wishes to be binary-compatible includes:
A) C++0x desires compatibility with *itself* on the *same* platform.
Compilers of different revisions from the same vendor would be able to 1A)
persistently write out and successfully read back the binary image of the object
in memory or 1B) pass-by-reference the data-structure to functions compiled by
different releases of the C++0x compiler from the same vendor. Compilers from
different vendors would be able to 1C) persistently write out and successfully
read back the binary image of the object in memory or 1D) pass-by-reference the
data-structure to functions compiled by a different vendor's C++0x compiler.
B) C++0x desires compatibility with *itself* on *different* platforms.
Compilers on different platforms (including different endianness) would be able
to communicate across a network (or persistently) such that a binary image of
the object in memory may be successfully exchanged with C++0x-compiled program
on another platform.
C) C++0x desires compatibility with language g on the same platform. C++98
already has extern "g" where g can be typically be C, Ada, Fortran, and Pascal.
D) C++0x desires compatibility with language g on different platforms.
I suspect that both David Abraham's and Uwe Schnitker's viewpoints discuss
only category 3 (and possibly category 1 too, implicitly). I appears that
categories 2 and 4 are omitted from David Abraham's and Uwe Schnitker's viewpoints.
In other words, once one starts pursuing this goal of controlling C++0x's
binary-layout for the purpose of binary-compatibility with X, it becomes a
slippery slope when people naturally start thinking of X as a *set* of topics
with which to be compatible instead of a *single* topic with which to be compatible.
Let's take layout of complex among different languages for example, so that
complex may be exhanged among different languages on the same platform (my
category C) in some proposed C++0x variation of complex standard library. Let
us first assume that the set of languages is C99 and C++0x. This point-to-point
case is not too hard: C++0x should use C99's binary-layout to achieve
equal-peer full-read full-write compatibility (my category 4). But when we add
Ada, Fortran, APL, Mathematica, Maple V, and who knows what else into the list,
it is likely that there ceases to be a *single* binary-layout for all languages'
complex-type which is sharable among all complex-number-capable languages on the
same platform. This problem of finding a single lingua-franca-layout for
complex becomes far worse when multiple platforms are added to the fray. Then
what? Do we say "Tough, C++0x standard library's complex is compatible with
Fortran's complex because that is the source-code base which we wish to subsume
and to heck with you people whose language is not Fortran."?
Instead of a complex fragile oft-misinterpreted rule-set of hackery of what
is & what is not a POD accompanied by a legend&lore handing down where & where
not such a contrived POD can be applied, I recommend either 1) leaving the whole
matter exactly as it is in C++98 or 2) embracing the full complexity of all 4
categories of the topic (and recognizing that categories 3 and 4 both have an
n-ary-fanout decomposition of their own). Partial solutions are only a partial
end (and thus perennial commencement) to an eternal argument over with what is
C++0x's layout to be compatible.
If you don't like this example of complex numbers in cartesian coordinates,
pick some other type with even less likelihood of having exactly the same
representation among all languages on the same platform, let alone the more
challenging case of all languages on all platforms (e.g., matrix, vector, wide
character string, multibyte character string, or for that matter, even
byte-sized character string as different string representations exist among
languages).
I doubt that rig-it-up-this-way/jigger-it-that-way rules in the C++0x
language standard (or any language standard for that matter) is the place for
such establishment of lingua franca binary-layouts. Instead this is the domain
of a data-marshalling protocol such as Sun's XDR, CORBA's IIOP, ITU's BER, or
even binary encodings of W3's XML to which C++0x should defer the topic. Hey,
now there is a rare concept: one standard's body leveraging another standards
body's previously-existing standard, rather than re-inventing their own variant
when entering previously-standardized territory.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 23 Aug 2002 10:25:14 GMT Raw View
Natale Fietta wrote:
....
> As a friend ponted out in a private mail a POD can not have any base
> class, i'm a bit surprised from this, what is the rationale for this
> requirement ?
Because standard C structs can't have base classes.
....
> So, if i understand correctly, a POD type is defined to be not only
> passable to C function but also can be created, copied and destructed
> from C code.
That's a goal, rather than a definition.
> Do exist in the standard a similar definition for less stringent
> requirements?
No, there's a list of features that are prohibited in POD types. The
reason why they're prohibited is not provided in any detail. My
knowledge of the reason is mainly from extensive discussions on this
newsgroup, and partly from reverse-engineering the standard.
> I do mean: if i want only to pass to a C function a pointer to a const
> instance of my class (my english is not too good, i do mean
> c_function(const MyClass*);) i do not need a fully compliant POD
> class, do exist a standard name for classes of this type ?
If you only want to pass a pointer to it, things are a lot simpler. As
long as you make no attempt to de-reference or increment that pointer
from within C code, the class can have just about any characteristics
you like. Just pass it back to an extern "C" function compiled with C++,
in order to do the actual dereferencing.
However, if you want to actually use the pointer, you need to provide a
C struct definition that matches the layout of the C++ class. If it has
any feature which makes it not a POD type, you're pretty much out of
luck. Even if it is a POD type, there's still potential problems (which
I'll have to be vague about until I can get the scratches removed from
the backup CD that contains my copy of the standard). :-(
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: schnitker@sigma-c.com (Uwe Schnitker)
Date: Fri, 23 Aug 2002 11:11:31 CST Raw View
Daniel Miller <daniel.miller@tellabs.com> wrote in message news:<3D654BF6.3060101@tellabs.com>...
<SNIP> BTW: I like your Master-Servant... description.
> Thus I applaud both David Abraham's and Uwe Schnitker's viewpoints
Thank you.
> which provided a multi-categorized set of expectations for a POD versus an
> enhanced-POD or a 4-branch if-else set of rules. In reality (outside of
> standardese) there is not merely one true C++98-esque definition of POD, but
> rather at least 2 in David Abraham's POD/enhanced-POD scheme and at least 4
> in Uwe Schnitker's & Dan'l Miller's schemes. (I am unclear whether the set
> of 4 categories in Uwe Schnitker's scheme and the set of 4 categories in
> Dan'l Miller's scheme are exactly congruent because I am unfamiliar with the
> verb "green-card" [but rather only with the noun "green-card" in the USA's
> Immigration & Naturalization Service context of permanent resident prior to
> full citizenship].)
I (ab)used "green card" as a verb to describe a process superficially similiar
to "Immigration & Naturalization": Oject created outside C++ might be used
within C++ with added functionality (even if they are not POD's).
<SNIP>
> Conversely, I find the whole topic of rule-based it-has-this
> it-doesn't-have-that definition of POD (or enhanced-POD or
> copyable/"greencard"able POD) at best a contrived hack
It is not a hack! The rules are not arbitrary. They just follow the reality
and describe - or want to prescribe - what already works on "typical"
plattforms. (I'm delibrately fussy about "typical".)
(In german: "Die normative Kraft des Faktischen anerkennen...")
> and at worst combustible
> fuel for endless debate & confusion & argument (as it is already today in
> C++98).
Yes. Yes. That's a very valid argument. Please allow me to be boring just once:
"As simple as possible, ..."
> If certain interest groups wish to address the binary-compatibility problem
> at all in C++0x, then I request that C++0x take a more-disciplined
> less-hack'nstance approach.
Nobody talked about "binary" compatibillity. ABI problems are traditionally
not considered by the C++ standard.
Also note that some of the presented issues are about enabling additional
optimizations within C++.
> First, regarding binary-compability, one must specifically itemize *with
> what* one desires compatibility. One cannot be merely "compatible"; one can
> only be "compatible *with*" something.
The traditional answer is: Some aspects of C++ are compatible with the
respective aspects of C, provided you are using the C compiler from the
same vendor. Since on many plattforms there is a de-facto C ABI standard,
which is also used by other languages (FORTRAN), this compability has some
fan-out.
In essence it is a tautology: The standard gurantees that e.g. POD's are
compatible with systems for which they are compatible.
> A) C++0x desires compatibility with *itself* on the *same* platform.
> B) C++0x desires compatibility with *itself* on *different* platforms.
> C) C++0x desires compatibility with language g on the same platform.
> D) C++0x desires compatibility with language g on different platforms.
> I suspect that both David Abraham's and Uwe Schnitker's viewpoints discuss
> only category 3
True. (And even "same plattform" must be more constrained.)
> (and possibly category 1 too, implicitly).
No. This is an ABI question, and as such not addressed.
> I appears that categories 2 and 4 are omitted from David Abraham's and
> Uwe Schnitker's viewpoints.
Yes. They are somewhat contrary to the presented topic: The discussion
concentrated on allowing direct, immediate access to data, while allowing
cross-plattform compatibility needs some interpretative step, e.g. to
take care of endianness.
<SNIP>
> I doubt that rig-it-up-this-way/jigger-it-that-way rules in the C++0x
> language standard (or any language standard for that matter) is the place for
> such establishment of lingua franca binary-layouts.
> Instead this is the domain of a data-marshalling protocol such as Sun's XDR,
> CORBA's IIOP, ITU's BER, or even binary encodings of W3's XML to which C++0x
> should defer the topic.
Yes. You're right. But, as I tried to explain, we were talking about a very
different, and far more humble, suggestion.
> Hey, now there is a rare concept: one standard's body
> leveraging another standards body's previously-existing standard, rather than
> re-inventing their own variant when entering previously-standardized
> territory.
A very nice idea. But you get into problems with different standards evolving
differently. See C (89 / 99) vs. C++ (98 / 0x).
Regards,
Uwe
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Daniel Miller <daniel.miller@tellabs.com>
Date: Fri, 23 Aug 2002 22:27:07 GMT Raw View
Daniel Miller wrote:
> I suspect that both David Abraham's and Uwe Schnitker's viewpoints
> discuss only category 3 (and possibly category 1 too, implicitly). I
> appears that categories 2 and 4 are omitted from David Abraham's and Uwe
> Schnitker's viewpoints.
This paragraph's reference to numeric categories should have been alphabetic
categories. Corrected:
I suspect that both David Abraham's and Uwe Schnitker's viewpoints
discuss category C (and possibly category A too, implicitly). I
appears that categories B and D are omitted from David Abraham's and Uwe
Schnitker's viewpoints (and possibly category A as well).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Mon, 26 Aug 2002 00:25:46 GMT Raw View
On 23 Aug 2002 10:25:14 GMT, "James Russell Kuyper Jr."
<kuyper@wizard.net> wrote:
>Natale Fietta wrote:
>....
>> As a friend ponted out in a private mail a POD can not have any base
>> class, i'm a bit surprised from this, what is the rationale for this
>> requirement ?
>
>Because standard C structs can't have base classes.
To me this do not seem a sufficient reason, consider this simple
example:
struct Base
{
int i;
float f;
}
struct Derived : public Base
{
char c;
}
If both type are otherwise POD's why do not require Derived to be
memory layout equivalent to this ?
struct C_compatible_Derived
{
//Base data members
int i;
float f;
//Derived data members
char c;
}
this can be of big pratical usefulness, i think.
>> I do mean: if i want only to pass to a C function a pointer to a const
>> instance of my class (my english is not too good, i do mean
>> c_function(const MyClass*);) i do not need a fully compliant POD
>> class, do exist a standard name for classes of this type ?
...
>However, if you want to actually use the pointer, you need to provide a
>C struct definition that matches the layout of the C++ class.
It is the opposite, i do not write the C code, i am forced to use a C
API (sometime it is OS-API, sometime it is a commercial library) and i
want to interface with it from my C++ program, so i want to mimic the
memory layout of an already defined C struct into a C++ class.
as far as i know this is a very very common situation...
>If it has
>any feature which makes it not a POD type, you're pretty much out of
>luck. Even if it is a POD type, there's still potential problems
My humble opinion is that for any pratical point of view the standard
definition of POD is too stringent for this need, if the C code only
read the datas in the struct only the memory layout of my class is
important.
I want to take full advantage of C++ in my code, not to have to use
the C subset of C++ only because i need my data to be readable from
C-API's !
Regards,
Natale Fietta
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 26 Aug 2002 15:26:49 GMT Raw View
Natale Fietta wrote:
>
> On 23 Aug 2002 10:25:14 GMT, "James Russell Kuyper Jr."
> <kuyper@wizard.net> wrote:
>
> >Natale Fietta wrote:
> >....
> >> As a friend ponted out in a private mail a POD can not have any base
> >> class, i'm a bit surprised from this, what is the rationale for this
> >> requirement ?
> >
> >Because standard C structs can't have base classes.
>
> To me this do not seem a sufficient reason, consider this simple
> example:
>
> struct Base
> {
> int i;
> float f;
> }
>
> struct Derived : public Base
> {
> char c;
> }
>
> If both type are otherwise POD's why do not require Derived to be
> memory layout equivalent to this ?
>
> struct C_compatible_Derived
> {
> //Base data members
> int i;
> float f;
> //Derived data members
> char c;
> }
>
> this can be of big pratical usefulness, i think.
I'd say that the main reason is that such a guarantee is not needed, to
achieve the intended purpose of the POD classification. See below.
....
> >However, if you want to actually use the pointer, you need to provide a
> >C struct definition that matches the layout of the C++ class.
>
> It is the opposite, i do not write the C code, i am forced to use a C
> API (sometime it is OS-API, sometime it is a commercial library) and i
> want to interface with it from my C++ program, so i want to mimic the
> memory layout of an already defined C struct into a C++ class.
> as far as i know this is a very very common situation...
That's trivial. If you can write a C definition for a struct, that
definition can be carried over into C++, usually without any changes
needed, and is guaranteed to constitute a POD struct as far as C++ is
concerned. You can even add non-virtual member functions and static data
members to the C++ definition, and it will still be a POD struct.
> >If it has
> >any feature which makes it not a POD type, you're pretty much out of
> >luck. Even if it is a POD type, there's still potential problems
>
> My humble opinion is that for any pratical point of view the standard
> definition of POD is too stringent for this need, if the C code only
Of course it is. It's a simplified version of the "real" requirement for
that particular guarantee. That's because there are infinitely many
different ways you could categorize objects, and the standard can
reasonably standardize only a few of those ways. "POD" is overloaded for
several different meanings - I once made a list of 20 different
guarantees that the standard makes about POD types:
1.8 p5: POD's occupy contiguous storage
3.6.2 p1: static POD's "shall be initialized before any dynamic
initialization takes place"
3.8 p5: During the time that memory has been allocated for a POD object,
but outside it's lifetime, it is NOT undefined behavior to use a pointer
to that memory
- to access a non-static data member or call a non-static
member function
- as the operand of a static_cast<>
3.8 p6: says similar things to 3.8 p5 about lvalues.
3.9 p2: the contents of a POD object can be copied to a sufficiently
large array of 'char' or 'unsigned char' and back again without changing
the value of the object
3.9 p3: the contents of a POD can be copied using memcpy() to another
object of the same type; the value of the second object will be the same
as the value of the first.
5.2.2 p7: a POD object can be passed as one of the variable arguments of
a function
5.3.15 p15: a new-expression doesn't have to waste time initializing a
POD object of class type.
5.19 p4: the address of a POD member can be an address constant
expression.
5.19 p5: a reference to a POD member can be a reference constant
expression.
6.7 p3: you can jump from a place where a local automatic POD object is
not in scope, to one where it is in scope, so long as that object is
declared without an initializer.
6.7 p4: a local static POD object declared with initializers is
initialized before its block is first entered.
8.5 p5: default initialization of a POD object is zero initialization.
8.5 p9: if no initializer is specified for a POD, no initialization need
be done.
8.5.1 p14: if a static aggregate POD's initializers are constant
expressions, initialization occurs during the static phase of
initialization.
9.2 p14: "Two POD-struct types are layout-compatible if they have the
same number of members, and corresponding members (in order) have layout
compatible types"
9.2 p15: Similar statement about POD-unions.
9.2 p16: "If a POD-union contains two or more POD-structs that share a
common initial sequence, and if the POD-union contains one of these
POD-structs, it is permitted to inspect the common initial part of any
of them."
9.2 p17: "A pointer to a POD-struct, suitably converted using a
reinterpret_cast, points to its initial member (of if that member is a
bit-field, then to the unit in which it resides) and vice versa."
21 p1: Only a POD type may be used as the "character" type in the
standard's templated string classes.
The requirements for POD types are meant to be strict enough to allow
all 20 of those guarantees to apply simultaneously. That means, in
general, that those requirements are stricter than they need to be, for
any one of the particular guarantees.
Should the standard be re-written to create 20 different type
classifications, one for each of those guarantees, with the requirements
of each classification being tailored to be just exactly strict enough
to support that guarantee, and no stricter? I don't think so. The
purpose of the POD guarantees was to allow for backward compatibility.
Those guarantees cover commonplace code that was traditionally safe to
perform on any C type, which would not be safe when applied to a generic
C++ class. The POD classification was intended to allow C code to be
imported to C++ with neglible modification, by making it legal to write
such code for any data type that was sufficiently C-like.
The POD classification, and the guarantees connected to it, were not
intended for any more general purpose. As a rule, you should avoid
writting any C++ code that depends upon any of those guarantees.
....
> read the datas in the struct only the memory layout of my class is
> important.
> I want to take full advantage of C++ in my code, not to have to use
> the C subset of C++ only because i need my data to be readable from
> C-API's !
You don't have to restrict yourself to the C subset of C++. You can use
any C++ feature you want, so long as that feature doesn't make your
struct cease to be a POD type. You just need to know which features
those are.
Keep in mind that you're perfectly free to define a full-blown C++
class, that has an implicit conversion to and from the POD struct type
that you use for your C interface. Perform those conversions at the
appropriate places in your code, and you should be able to do just about
anything you want.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Mon, 19 Aug 2002 05:21:09 GMT Raw View
On Thu, 15 Aug 2002 23:59:10 GMT, "James Russell Kuyper Jr."
<kuyper@wizard.net> wrote:
> Natale Fietta wrote:
>> I'm not a language lawyer, probably i am not using the term POD in the
>> correct way, for me a POD is a class with a memory layout compatible
>> with a C struct. to obtain this it is necessary (and as far as i know
>> also sufficient) to have no virtual function, to have all datas in the
>> same section and to evitate multiple inheritance and virtual bases; is
>> this incorrect ?
>
>Those are all necessary. They're not quite sufficient. Among other
>things, all of the non-static data members must also have POD types.
Yes, i have forgotten to write it but i do know, obviously this
applies not only to non-static data members but also to base classes.
Other requirements ?
>> My vectors classes often have non trivial constructor, do this make
>> them non-POD ?
>
>Yes.
This confuse me, why the presence of a non trivial constructor make
the type non-POD ?
Do exist any real compiler who change the memory layout of a class
only because a user defined constructor exist ?
Regards,
Natale Fietta
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: 19 Aug 2002 17:30:01 GMT Raw View
ros0230@iperbole.bologna.it (Natale Fietta) wrote in message news:<3d5f6b7b.5500195@news.iperbole.bologna.it>...
> On Thu, 15 Aug 2002 23:59:10 GMT, "James Russell Kuyper Jr."
> <kuyper@wizard.net> wrote:
>
> > Natale Fietta wrote:
> >> I'm not a language lawyer, probably i am not using the term POD in the
> >> correct way, for me a POD is a class with a memory layout compatible
> >> with a C struct. to obtain this it is necessary (and as far as i know
> >> also sufficient) to have no virtual function, to have all datas in the
> >> same section and to evitate multiple inheritance and virtual bases; is
> >> this incorrect ?
> >
> >Those are all necessary. They're not quite sufficient. Among other
> >things, all of the non-static data members must also have POD types.
>
> Yes, i have forgotten to write it but i do know, obviously this
> applies not only to non-static data members but also to base classes.
>
> Other requirements ?
>
> >> My vectors classes often have non trivial constructor, do this make
> >> them non-POD ?
> >
> >Yes.
>
> This confuse me, why the presence of a non trivial constructor make
> the type non-POD ?
>
> Do exist any real compiler who change the memory layout of a class
> only because a user defined constructor exist ?
>
> Regards,
> Natale Fietta
>
Changing the layout due to the presence or absence of a non-trivial
ctor is not the issue with POD classes. The basic requirement for a
POD class, and the one from which all other requirements follow, is
that a POD class must be capable of being CORRECTLY copied using
memcpy. That is, the real basic requirement on a POD class is that
the bits contained in the POD data members can simply be copied as is
in order to obtain a valid copy of the POD class object.
This requirement itself follows naturally from the original source of
POD classes, which were C structs that, of course, had no ctors at all
and could be copied by the compiler. So the equivalence you should be
looking at for POD classes is that they match the requirements of a
C-style struct.
Randy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 19 Aug 2002 17:55:07 GMT Raw View
Natale Fietta wrote:
>
> On Thu, 15 Aug 2002 23:59:10 GMT, "James Russell Kuyper Jr."
> <kuyper@wizard.net> wrote:
>
> > Natale Fietta wrote:
> >> I'm not a language lawyer, probably i am not using the term POD in the
> >> correct way, for me a POD is a class with a memory layout compatible
> >> with a C struct. to obtain this it is necessary (and as far as i know
> >> also sufficient) to have no virtual function, to have all datas in the
> >> same section and to evitate multiple inheritance and virtual bases; is
> >> this incorrect ?
> >
> >Those are all necessary. They're not quite sufficient. Among other
> >things, all of the non-static data members must also have POD types.
>
> Yes, i have forgotten to write it but i do know, obviously this
> applies not only to non-static data members but also to base classes.
>
> Other requirements ?
My copy of the standard is currently inaccessible, but I think that's
most of the requirements.
> >> My vectors classes often have non trivial constructor, do this make
> >> them non-POD ?
> >
> >Yes.
>
> This confuse me, why the presence of a non trivial constructor make
> the type non-POD ?
>
> Do exist any real compiler who change the memory layout of a class
> only because a user defined constructor exist ?
A class that is otherwise a POD class, but happens to have a non-trivial
destructor, could always be implemented in a way that is
layout-compatible with C. The issue isn't feasibility, but good design.
The existence of non-trivial constructor implies that a constructor must
be used to create a valid instance of the object, which means it's not
truly "Plain Old Data", but something more active.
I can't argue that this is an absolutely compelling argument - it would
be perfectly possible to define an extern "C" factory function, compiled
in C++, that calls the C++ constructor to create correctly constructed
objects of that type from within C code. In C++, all you'd need to do to
encourage use of a factory function is make the constructors or
destructors private, and declare the factory function a friend. However,
there's no way to write a C declaration that would force the use of that
factory function from within C code.
It's not obvious that it's necessary to have the capability of correctly
constructing the objects from within C code. Nonetheless, that is the
reason why this decision was made.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Andrew Koenig <ark@research.att.com>
Date: 19 Aug 2002 18:00:12 GMT Raw View
Natale> Do exist any real compiler who change the memory layout of a
Natale> class only because a user defined constructor exist ?
It's not a question of the memory layout; it's a question of the
meaning of the memory. Once the class has a constructor, there is
no reason to believe that copying an object of that class is
equivalent to copying its memory.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: schnitker@sigma-c.com (Uwe Schnitker)
Date: Tue, 20 Aug 2002 18:46:28 GMT Raw View
Andrew Koenig <ark@research.att.com> wrote in message news:<yu99it27geu3.fsf@europa.research.att.com>...
> Natale> Do exist any real compiler who change the memory layout of a
> Natale> class only because a user defined constructor exist ?
>
> It's not a question of the memory layout; it's a question of the
> meaning of the memory.
Not neccessarily. The starting point of the discussion was the question
wether one can pass an array or std::vector of objects (small vectors)
to a C-API. This depends essentially on the memory layout being the
same for C and C++.
> Once the class has a constructor, there is
> no reason to believe that copying an object of that class is
> equivalent to copying its memory.
In the example of the small vectors you don't want to copy the objects.
Avoiding the copy is the reason to prefer a POD class over a class which
allows access to an underlying POD, like std::string and its c_str function.
You might not even want to be able to create objects from C. If the whole
point is being able to pass arrays of existing objects to a C-API, it is
sufficient to know that the data layout is identical.
So it would be nice if we had a guarantee about the layout for classes
which are not POD's, but "sufficiently close".
On a slightly different issue: While your assessment above is true in general,
there are special cases.
Citing again:
> Once the class has a constructor, there is
> no reason to believe that copying an object of that class is
> equivalent to copying its memory.
If a class contains only build-in data members, and the constructor is
only used to set the values of these and ensure proper initialization,
and especially if the class relies on the trivial, default generated copy
contructor and assignment operator, there is a lot of reason to "believe that
copying an object of that class is equivalent to copying its memory".
IMHO the "trivial-ness" of the destructor, copy constructor and assignment
operator is far more significant for POD-likeness than the mere existence
of simple user-defined constructors.
It is clear that the standard gives implementers any freedom to implement
things in a way that these consideration breaks down. But maybe a slightly
more permissive definition of POD'ness or a separate guarantee about data
layout compatibillity with C for "almost-POD's" would be useful.
Disclaimer: I'm not sure it would be worth the trouble.
Taking the latter idea to its logical end, you would have to define the border
conditions for a spectrum of possibillities:
- a class whose objects can be created by C code (now called POD)
- a class whose objects can be "mem-copied"
- a class whose objects can be "mem-moved" (thinking of YASLI, anyone?)
- a class whose objects can be passed-by-pointer to a C-API
While such a scheme would offer more flexibillity, it would also complicate
things a lot and present some new pitfalls.
Regards,
Uwe
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "David Abrahams" <david.abrahams@rcn.com>
Date: Wed, 21 Aug 2002 15:41:09 GMT Raw View
"Uwe Schnitker" <schnitker@sigma-c.com> wrote in message
news:aec458c5.0208192300.4812e81d@posting.google.com...
> Andrew Koenig <ark@research.att.com> wrote in message
news:<yu99it27geu3.fsf@europa.research.att.com>...
> > Natale> Do exist any real compiler who change the memory layout of a
> > Natale> class only because a user defined constructor exist ?
> >
> > It's not a question of the memory layout; it's a question of the
> > meaning of the memory.
>
> Not neccessarily. The starting point of the discussion was the question
> wether one can pass an array or std::vector of objects (small vectors)
> to a C-API. This depends essentially on the memory layout being the
> same for C and C++.
>
FYI:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1356.html
-Dave
-----------------------------------------------------------
David Abrahams * Boost Consulting
dave@boost-consulting.com * http://www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Thu, 22 Aug 2002 15:46:05 GMT Raw View
On 19 Aug 2002 17:55:07 GMT, "James Russell Kuyper Jr."
<kuyper@wizard.net> wrote:
>> >Those are all necessary. They're not quite sufficient. Among other
>> >things, all of the non-static data members must also have POD types.
>>
>> Yes, i have forgotten to write it but i do know, obviously this
>> applies not only to non-static data members but also to base classes.
>>
>> Other requirements ?
>
>My copy of the standard is currently inaccessible, but I think that's
>most of the requirements.
As a friend ponted out in a private mail a POD can not have any base
class, i'm a bit surprised from this, what is the rationale for this
requirement ?
>> This confuse me, why the presence of a non trivial constructor make
>> the type non-POD ?
<cut>
>It's not obvious that it's necessary to have the capability of correctly
>constructing the objects from within C code. Nonetheless, that is the
>reason why this decision was made.
So, if i understand correctly, a POD type is defined to be not only
passable to C function but also can be created, copied and destructed
from C code.
Do exist in the standard a similar definition for less stringent
requirements?
I do mean: if i want only to pass to a C function a pointer to a const
instance of my class (my english is not too good, i do mean
c_function(const MyClass*);) i do not need a fully compliant POD
class, do exist a standard name for classes of this type ?
Regards,
Natale Fietta
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: schnitker@sigma-c.com (Uwe Schnitker)
Date: Thu, 22 Aug 2002 16:50:49 GMT Raw View
"David Abrahams" <david.abrahams@rcn.com> wrote in message news:<ajut6f$3ek$1@bob.news.rcn.net>...
> "Uwe Schnitker" <schnitker@sigma-c.com> wrote in message
> news:aec458c5.0208192300.4812e81d@posting.google.com...
> > Andrew Koenig <ark@research.att.com> wrote in message
> news:<yu99it27geu3.fsf@europa.research.att.com>...
> > > Natale> Do exist any real compiler who change the memory layout of a
> > > Natale> class only because a user defined constructor exist ?
> > >
> > > It's not a question of the memory layout; it's a question of the
> > > meaning of the memory.
> >
> > Not neccessarily. The starting point of the discussion was the question
> > wether one can pass an array or std::vector of objects (small vectors)
> > to a C-API. This depends essentially on the memory layout being the
> > same for C and C++.
> >
>
>
> FYI:
>
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1356.html
>
>
> -Dave
Thanks a lot. I really enjoyed your concise - and, hopefully, convincing -
way to present the problem.
Some comments:
You don't mention a different, but closely related issue: Copying of memory
vs. copying of objects. The main reason for the inequivalency of them is,
AFAIK, that some internal or external data might not be adjusted as neccessary.
This is today only guaranteed not to happen for POD's.
Allowing "memcopying" for suitable non-POD's would enable some optimizations.
(It might also make it easier to interoperate with systems or languages which
use non-conservative garbage collections - I'm shooting from the hip here.)
Note that the neccessary constraints are stronger than those for layout-
predictabillity. A class which contains a pointer and manages it according
to the "rule of three" could still have a predictable layout, but memcopying
it might be disastrous, e.g. if the class manages a reference count.
Similar considerations apply to "constructing" an object externally, e.g.
allocating the momory and setting the data members of a struct in C and
use a pointer to it as a pointer to the corresponding C++ class/struct.
(One might call this "green-carding" the object. And no, I don't know if
this might be important.)
Possible new rules:
1)If a class or its members or bases have virtual functions or virtual bases,
its memory layout is implementation-dependent and objects of it may not be
memcopied or "green-carded".
2)Else if a class or its members or bases define at least one of the "famous
three", the class cannot be memcopied or "green-carded", but its memory
layout is predictable.
3)Else if a class or its members or bases define constructors (but not
copy constructors), the class can be memcopied or "green-carded" and
its memory layout is predictable.
4)Else the class is a true POD.
This rules would follow a "Only grant to compiler writers what they absolutely
need" principle. (Since I will probably never write on a C++ compiler I can
live with that ;-).)
BTW: Note that the "aggregate" definition is automatically satisfied in
case 4), but not in cases 2) and 3) - neither in your "Extended POD" case.
Just some lunch-time imaginations.
Uwe
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]