This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ object model and dynamic type


Hi,

On Wed, 3 Feb 2010, William M. (Mike) Miller wrote:

> > For example, would the following be a valid definition of 'f'?
> >
> > Â Â Âvoid f(int* p) {
> > Â Â Â Â new (p) float(1.2);
> > Â Â Â}
> >
> > My sense is that only objects of compatible types may be stored in
> > a variable, however I do not see a clear statement to that effect in the
> > standard text. ÂNote that restricting to objects of compatible types
> > still allows allocators that use static or automatic storage (since they
> > would be using arrays of characters.)
> 
> 3.8p7-9 are intended to address concerns such as these.  The
> existing wording primarily addresses class objects and particularly
> class objects with destructors (p7, for instance, which most directly
> applies to your example and requires that the old and new objects
> have the same type, only applies after the lifetime of the original
> object has ended, which only occurs for scalar objects when their
> storage is freed), so we probably need to tweak it a bit to make it
> clear that non-class objects are also covered.

Note that just more explicitely including non-class objects alone will not 
render the above definition of 'f' invalid (the program as given will be 
invalid, for multiple reasons, one of them 3.8p7).  In particular:
- p9 talks about const objects,
- p7 talks about possibilities of when it's possible to use a 
  pointer, reference or name of the original object to refer to the new 
  object (amongst other things when the new type is the same as the old 
  type)
- p8 talks about what is required for types with non-trivial dtors.

p9 doesn't apply in our example, p7 does apply and already now seems to 
make your example program invalid, but see below.  p8 doesn't apply right 
now, but could be made to apply by removing the restriction on non-trivial 
dtors.  Then it applies and also renders the program invalid.  Good.  Now 
rewrite the program like so:

 Â Âint g() {
 Â Â Â int i = 3;
 Â Â Â int* p = &i;
       new (p) float (1.2);
       useme((float*)p);
       new (p) int (42);
 Â Â Â return i;
 Â Â}

Note how p8 (even without the dtor restriction) doesn't render this 
program invalid (at scope exit the storage in question holds an object of 
the declared type).  p7 also doesn't render this invalid: while the 
storage holds a float we don't refer to it via the original name, we have 
no reference, and we use a pointer to a different object, not the original 
pointer (assume that useme() only accesses this as float).  And when we 
use the original name 'i' later the storage indeed fulfills the 
requirements of p7 again.

It would be good to clarify if it's intended that such program be valid, 
or if also such intermediate reuse of storage (with proper restoring of 
declared types) is intended to be invalid.


Ciao,
Michael.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]