Re: Object layout guarantees and manual pointer adjustments
On 18 Apr., 03:07, t...@42.sci.utah.edu wrote:
Francis Glassborow <francis.glassbo...@btinternet.com> wrote:
The base memory for a complete object must be contiguous. If this was
not the case then it would be impossible to create objects dynamically
with placement new (the version where the programmer provides the memory)
I do not think this is true, but see my comment below; it depends on
what we mean by `contiguous'.
[...]
You might have meant that the whole object is contiguous, if one
includes the additional spacing which a compiler is allowed to insert
(that is, it depends what we mean by `contiguous'). I think but have
not verified that this is true.
Yes, that's probably what he meant. To summarize this assumption in
my own words:
"A complete object 'o' (complete = it's not a base class subobject
of another object) is completely contained within a consecutive
sequence of bytes that starts at the address static_cast<void*>(&o)
and is of length sizeof(o)."
I don't think the C++ standard leaves room for anything else
considering custom new operators, placement new, etc.
What's left is: Is the layout guaranteed to be consistent among
different instances of the same *complete* type?
Given the OPs question though, I'm not sure that such a guarantee,
true or not, would be useful.
I understand the skepticism. Usually, when someone asks questions
like these, there's a much better alternative. I wouldn't have
thought that such guarantees can be useful until recently.
I was trying to write (explore) something like this:
http://img245.imageshack.us/img245/5633/cow.png
The polymorphic requirement forced me to use an abstract class that
doesn't mention any template type parameters in its interface. The
problem arises when I clone the "wrapper" object pointed to via
"paw". Consider this:
concrete_wrapper<U>* pcw = new concrete_wrapper<U>(...);
T* ptr1 = pcw->get(); // returns address of wrapped object that
// is convertible to T*. The function 'get'
// is not part of the abstract interface
abstract_wrapper* paw1 = pcw;
// we now "forget" what the type U was and only
// have 'paw1' and 'ptr1' available at runtime.
abstract_wrapper* paw2 = paw1->clone();
T* ptr2 = ???
The dynamic type of the new wrapper object pointed to by "paw2" is
known to be exactly the same as the dynamic type of the object pointed
to by "paw1". But the type information about U is gone. Still, I'd
like to be able to initialize "ptr2" with the correct value so that it
points to the new copy of the cloned member object. In case the
layouts are known to be equal this "manual pointer adjustment" trick
from the first post could be applied to compute the correct value for
"ptr2".
Admittedly, it's a rather ugly "solution". But so far I wasn't able
to come up with a less ugly implementation that meets all the design
goals. It's more of a puzzle right now. I'm aware that it may not be
very useful in practise.
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]