Topic: size of empty class?
Author: David R Tribble <david@tribble.com>
Date: 1999/06/25 Raw View
Scott Meyers wrote:
>
> On 4 Jun 1999 19:44:07 GMT, Martin von Loewis wrote:
>> You mean, objects using alternate bytes? That is certainly possible,
>> and there's nothing wrong with it. Only POD objects need to occupy
>> contiguous space. A virtual base is found often through a pointer in
>> the derived object, and there may be cases where you want to store
>> the base object in a completely unrelated region of memory.
>
> I don't think this is allowed. If I say
>
> T *p = new T;
>
> that may yield a call to T::operator new, and that function expects to
> allocate all the memory for the complete T object. Otherwise there
> would be little point in being able to write operator new.
> Furthermore, operator new is allowed only to return a pointer to one
> chunk of (contiguous) memory. I conclude that an object must be in a
> single chunk of memory (which is, I think, the official definition of
> "object", anyway). This still allows for the base class fields of a
> derived object to be located either above or below the derived class
> fields (or a combination of both, I suppose), but all the data for a
> complete object must be in a single chunk of contiguous memory.
Assume for the moment that it is possible for a derived object to
exist as two separate chunks, the derived part and the base part, as
long as a polymorphic pointer to the base part can be downcast into
a pointer to the derived part, and visa versa (which implies that
such a split object must have extra information embedded within its
parts). Writing 'new' and 'delete' operators for this kind of
implementation would probably be impossible, since the programmer
probably doesn't know about this hidden information; indeed, the
standard's description of the 'new' and 'delete' operators doesn't
mention anything of this nature. So I conclude that the base part
of a derived object lies within the same memory chunk as the rest
of the object.
On the other hand, I can think of a twisted 'new' operator for a
class that allocates extra memory outside of the object, perhaps
even saving its address in a pointer member of the object (since it
knows the structure of its class); the corresponding 'delete'
operator would of course have to free this extra memory:
class Foo
{
private:
Bar * m_bar;
...
public:
static void * operator new(size_t sz);
static void operator delete(void *p);
};
void * Foo::operator new(size_t sz)
{
Foo * p = (Foo *) malloc(sz); // 1st chunk
p->m_bar = new Bar; // 2nd chunk
return p;
}
void Foo::operator delete(void *p)
{
Foo * f = (Foo *) p;
delete f->m_bar; // 2nd chunk
free(p); // 1st chunk
}
This doesn't really break the rule that an "object" must reside in
a "single contiguous chunk" of memory. But it does allocate more
than one memory chunk during object allocation. Is this conforming
(I suspect not)?
-- David R. Tribble, dtribble@technologist.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: scorp@btinternet.com (Dave Harris)
Date: 1999/06/26 Raw View
david@tribble.com (David R Tribble) wrote:
> Assume for the moment that it is possible for a derived object to
> exist as two separate chunks, the derived part and the base part, as
> long as a polymorphic pointer to the base part can be downcast into
> a pointer to the derived part, and visa versa (which implies that
> such a split object must have extra information embedded within its
> parts). Writing 'new' and 'delete' operators for this kind of
> implementation would probably be impossible, since the programmer
> probably doesn't know about this hidden information; indeed, the
> standard's description of the 'new' and 'delete' operators doesn't
> mention anything of this nature. So I conclude that the base part
> of a derived object lies within the same memory chunk as the rest
> of the object.
Can't the compiler call operator new() twice, once for each chunk? The
author of the operator would just know how to allocate memory chunks of
the requested size. The compiler would glue them together to make the
composite object.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david@tribble.com>
Date: 1999/06/24 Raw View
Scott Meyers wrote:
>
> James.Kanze@dresdner-bank.com wrote:
> >...
> > Basically, for a POD, I can copy the memory image elsewhere using
> > memcpy, copy it back, and get the same value. The implicit is that
> > doing this doesn't modify the value of any other variables.
>
> I must be dense, but I don't see why you can't do this with C++
> objects. Suppose I have object X and I memcpy it to some other
> location. I then memcpy it back to the memory for X. X has exactly
> the same bits now as it did before the copy. Even if some object were
> interleaved with X (which I really don't think is allowed), that
> object, too, would have exactly the same bits it did before. So what
> could have changed? (I'm assuming here that nothing else happens
> between the time X is memcpy'd and the time it's memcpy'd back.)
Provided that the second copying copies the bits back into the
original location, I agree. But there could be weird implementations
that store something in the bits of an object's _vtbl (or some other
hidden piece of the object) that depends on the page address of the
object; in which case copying the object to a different page address
would corrupt the _vtbl bits.
-- David R. Tribble, dtribble@technologist.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Tom Payne <thp@hill.cs.ucr.edu>
Date: 1999/06/24 Raw View
Scott Meyers <smeyers@aristeia.com> wrote:
: I must be dense, but I don't see why you can't do this with C++ objects.
: Suppose I have object X and I memcpy it to some other location. I then
: memcpy it back to the memory for X. X has exactly the same bits now as it
: did before the copy. Even if some object were interleaved with X (which I
: really don't think is allowed), that object, too, would have exactly the
: same bits it did before. So what could have changed? (I'm assuming here
: that nothing else happens between the time X is memcpy'd and the time it's
: memcpy'd back.)
But if that other object got updated in the interim, the second memcpy
would destroy that new value. Is memcpy allowed to do that, i.e.,
when I memcpy sizeof(X) bytes to &X, is that allowed to change the
value of some other variable?
Tom Payne
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James.Kanze@dresdner-bank.com
Date: 1999/06/24 Raw View
In article <MPG.11d972b82e607e119896b8@news.teleport.com>,
smeyers@aristeia.com (Scott Meyers) wrote:
> > On the other hand, I've thought about it some more, and I'm now
fairly
> > convinced that POD objects, at least, cannot be interleaved, due to
an
> > implicit guarantee. (But does the implicit guarantee exist. I'd be
> > hard pressed to find it in either the C or the C++ standard.)
> > Basically, for a POD, I can copy the memory image elsewhere using
> > memcpy, copy it back, and get the same value. The implicit is that
> > doing this doesn't modify the value of any other variables.
> I must be dense, but I don't see why you can't do this with C++
objects.
> Suppose I have object X and I memcpy it to some other location. I
then
> memcpy it back to the memory for X. X has exactly the same bits now
as it
> did before the copy. Even if some object were interleaved with X
(which I
^
You meant with Y, didn't you.
> really don't think is allowed), that object, too, would have exactly
the
> same bits it did before. So what could have changed? (I'm assuming
here
> that nothing else happens between the time X is memcpy'd and the time
it's
> memcpy'd back.)
Y might have been changed in the meantime. memcpy'ing to X should not
change the value of Y back to an old value.
--
James Kanze mailto:
James.Kanze@dresdner-bank.com
Conseils en informatique orientie objet/
Beratung in objekt orientierter
Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49 (069) 63 19 86
27
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James.Kanze@dresdner-bank.com
Date: 1999/06/22 Raw View
In article <MPG.11d4873aea5efda59896b7@news.teleport.com>,
smeyers@aristeia.com (Scott Meyers) wrote:
>
> On 4 Jun 1999 19:44:07 GMT, Martin von Loewis wrote:
> > You mean, objects using alternate bytes? That is certainly possible,
> > and there's nothing wrong with it. Only POD objects need to occupy
> > contiguous space. A virtual base is found often through a pointer in
> > the derived object, and there may be cases where you want to store
the
> > base object in a completely unrelated region of memory.
>
> I don't think this is allowed. If I say
>
> T *p = new T;
>
> that may yield a call to T::operator new, and that function expects to
> allocate all the memory for the complete T object. Otherwise there would
> be little point in being able to write operator new. Furthermore, operator
> new is allowed only to return a pointer to one chunk of (contiguous)
> memory. I conclude that an object must be in a single chunk of memory
> (which is, I think, the official definition of "object", anyway). This
> still allows for the base class fields of a derived object to be located
> either above or below the derived class fields (or a combination of both, I
> suppose), but all the data for a complete object must be in a single chunk
> of contiguous memory.
The compiler is allowed to insert padding, which is reflected in the
sizeof. If you don't consider the padding formally part of the object,
there can be holes in it.
On the other hand, I've thought about it some more, and I'm now fairly
convinced that POD objects, at least, cannot be interleaved, due to an
implicit guarantee. (But does the implicit guarantee exist. I'd be
hard pressed to find it in either the C or the C++ standard.)
Basically, for a POD, I can copy the memory image elsewhere using
memcpy, copy it back, and get the same value. The implicit is that
doing this doesn't modify the value of any other variables.
--
James Kanze mailto:
James.Kanze@dresdner-bank.com
Conseils en informatique orient e objet/
Beratung in objekt orientierter
Datenverarbeitung
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany Tel. +49 (069) 63 19 86
27
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/06/23 Raw View
On 22 Jun 1999 15:49:14 GMT, James.Kanze@dresdner-bank.com wrote:
> The compiler is allowed to insert padding, which is reflected in the
> sizeof. If you don't consider the padding formally part of the object,
> there can be holes in it.
My primary objection was to Martin's claim that
A virtual base is found often through a pointer in the derived object,
and there may be cases where you want to store the base object in a
completely unrelated region of memory.
Interestingly, the standard (in 1.8/5) states that a POD type must occupy
contiguous bytes of storage, but we know that POD types may contain
padding, too. I'm not sure what that implies about whether padding bytes
are part of an object.
> On the other hand, I've thought about it some more, and I'm now fairly
> convinced that POD objects, at least, cannot be interleaved, due to an
> implicit guarantee. (But does the implicit guarantee exist. I'd be
> hard pressed to find it in either the C or the C++ standard.)
> Basically, for a POD, I can copy the memory image elsewhere using
> memcpy, copy it back, and get the same value. The implicit is that
> doing this doesn't modify the value of any other variables.
I must be dense, but I don't see why you can't do this with C++ objects.
Suppose I have object X and I memcpy it to some other location. I then
memcpy it back to the memory for X. X has exactly the same bits now as it
did before the copy. Even if some object were interleaved with X (which I
really don't think is allowed), that object, too, would have exactly the
same bits it did before. So what could have changed? (I'm assuming here
that nothing else happens between the time X is memcpy'd and the time it's
memcpy'd back.)
Scott
--
Scott Meyers, Ph.D. smeyers@aristeia.com
Software Development Consultant http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/06/21 Raw View
On 4 Jun 1999 19:44:07 GMT, Martin von Loewis wrote:
> You mean, objects using alternate bytes? That is certainly possible,
> and there's nothing wrong with it. Only POD objects need to occupy
> contiguous space. A virtual base is found often through a pointer in
> the derived object, and there may be cases where you want to store the
> base object in a completely unrelated region of memory.
I don't think this is allowed. If I say
T *p = new T;
that may yield a call to T::operator new, and that function expects to
allocate all the memory for the complete T object. Otherwise there would
be little point in being able to write operator new. Furthermore, operator
new is allowed only to return a pointer to one chunk of (contiguous)
memory. I conclude that an object must be in a single chunk of memory
(which is, I think, the official definition of "object", anyway). This
still allows for the base class fields of a derived object to be located
either above or below the derived class fields (or a combination of both, I
suppose), but all the data for a complete object must be in a single chunk
of contiguous memory.
Scott
--
Scott Meyers, Ph.D. smeyers@aristeia.com
Software Development Consultant http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/06/07 Raw View
Martin von Loewis wrote:
>
> James.Kanze@dresdner-bank.com writes:
>
> > Section 5.10: "Two pointers of the same type compare equal if and only
> > if they are both null, both point to the same object or function, or
> > both point one past the end of the same array."
>
> Well, that would still allow to partially overlap two objects (of same
> type, or of different type).
>
> This is not a theoretical question: I find that people quite often try
> to instantiate different objects in the same location, using
> placement-new, and explicit calls to the destructor. I always answered
> that this is undefined because no two objects may occupy the same
> space, but I don't see where this is undefined.
That should be perfectly safe if the memory is large enough and suitably
aligned for either type, and if every placement-new is preceded by one
and only one explicit destructor call using the previous object's type.
Then you'd never have the two objects occupying the same memory at the
same time. Also, if the original object was allocated statically or
automatically, the storage must be returned to it's original type before
the object's lifetime ends - even if it ends by means of a thrown
exception!
Is someone seriously expecting that it's safe to use the same memory two
different ways at the same time?!
> > A bit far-fetched, but could an implementation interleave class type
> > objects? Say, by using only even words. And then overlap two class
> > type objects?
>
> You mean, objects using alternate bytes? That is certainly possible,
> and there's nothing wrong with it. Only POD objects need to occupy
> contiguous space. A virtual base is found often through a pointer in
Class type objects can contain non-POD classes, and even ordinary
objects. I have a hard time seeing how the individual member objects
could be successfully interleaved. The only way I can see it is if the
relationship between pointers and addresses is fundamentally bizarre:
the low order bits of the physical address are logically rotated, so
that the low order bit of the address is not changed every time a
pointer advances by 1 byte. That would work precisely because physically
interleaved objects would not be interleaved in any way that would be
meaningful to C++.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/06/07 Raw View
James.Kanze@dresdner-bank.com wrote in message
<7j8r96$fqj$1@nnrp1.deja.com>...
>A bit far-fetched, but could an implementation interleave class type
>objects? Say, by using only even words. And then overlap two class
>type objects? (No implementation will ever do this, of course, but what
>text in the standard forbids it?)
I'll take a shot. Assume two-char size and alignment for ints, but structs
(not containing ints) may have 1-char alignment.
struct hole
{
hole(){}
char a;
// Compiler inserts padding here
int b;
} h;
Note that hole is not POD (ctor) and contains some "wasted" space. Since it
is not POD the memcpy() rules don't apply. Also assert((void*)&h.a <
(void*)&h.b). So for this implementation sizeof(hole) might be four. Now
add
struct ch
{
char d;
}; // sizeof(ch) == 1 on this implementation
struct combined: hole, ch {} comb;
It seems like a smart compiler might have sizeof(comb) == 4 and
&comb.d == &comb.a+1
It seems like such an implementation would be conforming.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fysx <fysx@spots.ab.ca>
Date: 1999/06/03 Raw View
Does the standard specify the size of an instance of this?
class empty {};
??
I was considering zero, but a colleague pointed out that an array of
pointer to empty would require instance to have a size greater then zero
so that each instance would have a unique address.
That means that the following can not optimize out the memory allocation
call
void func() {
empty* temp = new empty();
temp->some_function();
delete temp;
}
(the above assumes that some_function is the only member of empty)
Is there a reference fort his in C++ The Programming Language 3rd
Edition? Is the ARM more descriptive in language definition standards?
Thanks
Maxwell Sayles
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/06/03 Raw View
fysx <fysx@spots.ab.ca> writes:
>Does the standard specify the size of an instance of this?
>class empty {};
It says in clause 9, paragraph 3 that a complete object cannot
have zero size. In addition, the size cannot be negative. :-)
>I was considering zero, but a colleague pointed out that an array of
>pointer to empty would require instance to have a size greater then zero
>so that each instance would have a unique address.
Right.
>That means that the following can not optimize out the memory allocation
>call
>void func() {
> empty* temp = new empty();
> temp->some_function();
> delete temp;
>}
Right.
But if your class has no data and no virtual functions, all the
member functions can be static and you never need to create an
object at all. You can call a static member function with the syntax
empty::some_function();
If the class has data or virtual functions, it's creation
could not be optimized away in any event.
You didn't ask, but the non-zero size requirement applies to
complete objects. If a type is a subobject such as a base
class, it is possible for it to occupy no storage of its own.
--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/06/03 Raw View
fysx <fysx@spots.ab.ca> writes:
> Does the standard specify the size of an instance of this?
>
> class empty {};
These are really many questions. One is
What is sizeof(empty)?
This is answered in [expr.sizeof]/2
# The size of a most derived class shall be greater than zero (1.8).
> I was considering zero, but a colleague pointed out that an array of
> pointer to empty would require instance to have a size greater then zero
> so that each instance would have a unique address.
Yes. [intro.object]/5 says
# Unless it is a bit=ADfield (9.6), a most derived object shall have a
# non=ADzero size and shall occupy one or more bytes of storage.
I tried to find a clause saying that two complete objects may never
share the same storage, but this requirement is apparently not there.
> That means that the following can not optimize out the memory allocation
> call
>
> void func() {
> empty* temp =3D new empty();
> temp->some_function();
> delete temp;
> }
Of course it can, provided that it knows what some_function does.
This is the as-if rule: As long as you can't tell the difference, the
compiler might implement things in any way.
> Is there a reference fort his in C++ The Programming Language 3rd
> Edition? Is the ARM more descriptive in language definition standards?
Forget about the ARM, I'd say. The only true reference for such issues
is the C++ standard.
Regards,
Martin
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James.Kanze@dresdner-bank.com
Date: 1999/06/04 Raw View
In article <p6qu2spp41q.fsf@pandora.inst-inf-1.hu-berlin.de>,
Martin von Loewis <loewis@informatik.hu-berlin.de> wrote:
> I tried to find a clause saying that two complete objects may never
> share the same storage, but this requirement is apparently not there.
Section 5.10: "Two pointers of the same type compare equal if and only
if they are both null, both point to the same object or function, or
both point one past the end of the same array." Not very direct, but
I'd like to see how to implement it if two complete objects share the
same storage. (Perhaps with segmented memory.)
More generally, but only valid for POD's, are the requirements that you
can memcpy in and out (presumably not modifying other objects).
A bit far-fetched, but could an implementation interleave class type
objects? Say, by using only even words. And then overlap two class
type objects? (No implementation will ever do this, of course, but what
text in the standard forbids it?)
--
James Kanze mailto:
James.Kanze@dresdner-bank.com
Conseils en informatique orientie objet/
Beratung in objekt orientierter
Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49 (069) 63 19 86
27
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/06/04 Raw View
James.Kanze@dresdner-bank.com writes:
> Section 5.10: "Two pointers of the same type compare equal if and only
> if they are both null, both point to the same object or function, or
> both point one past the end of the same array."
Well, that would still allow to partially overlap two objects (of same
type, or of different type).
This is not a theoretical question: I find that people quite often try
to instantiate different objects in the same location, using
placement-new, and explicit calls to the destructor. I always answered
that this is undefined because no two objects may occupy the same
space, but I don't see where this is undefined.
> A bit far-fetched, but could an implementation interleave class type
> objects? Say, by using only even words. And then overlap two class
> type objects?
You mean, objects using alternate bytes? That is certainly possible,
and there's nothing wrong with it. Only POD objects need to occupy
contiguous space. A virtual base is found often through a pointer in
the derived object, and there may be cases where you want to store the
base object in a completely unrelated region of memory.
Regards,
Martin
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]