www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5895] New: clear() doesn't work as expected for pointers to structs

reply d-bugmail puremagic.com writes:

           Summary: clear() doesn't work as expected for pointers to
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: metalcaedes gmail.com

--- Comment #0 from Daniel Gibson <metalcaedes gmail.com> 2011-04-26 17:49:02
PDT ---
AFAIK the main purpose of clear() is to call the destructor of it's argument
and possibly invalidate it - this has been communicated in the d.D NG, however
there's no official documentation on clear().

So it's a surprise that the following code compiles without any warnings but
doesn't call Bar's destructor:

  struct Bar { ~this(){ writefln("bye"); } }
  Bar *b = new Bar();

Instead it just does "b=b.init;" or something like that - I don't need clear
for that.
Especially because clear has been advertised as finally replacing delete I'd
expect clear(b); to call b's destructor, even though b is just a pointer to a

Looking at clear()s implementation it's obvious what happens: b's type is
neither a class, a struct nor an array, so it's set to b.init.

So how can this be fixed? Some possibilities:

1. Dereference pointers (to structs or any pointers?) and clear the resulting
type? (what about pointers to pointers?)
2. Disallow clear() for anything but classes and structs? Writing x = x.init;
oneself isn't that hard, but this may not be bad for generic code that is
supposed to work with both simple and custom types. 
  2.1 Dereference pointers to structs
  2.2 Don't dereference pointers to structs but force the programmer to do it
himself with an appropriate error
3. Disallow clear() only for pointers (but not for int etc)? A bit better for
generic code I guess. Has the same sub-options as 2.

4. Keep clear() the way it is but introduce another function especially for
structs and objects that does the dereferencing if necessary
5. Like 2. but introduce another function that behaves like the current clear()

IMHO any change is possible because clear() isn't officially documented yet.
But because it has often been mentioned in NG posts as something like delete
for people who want to explicitly call the destructor, I'd prefer one of
options 1. to 3.

NG Thread discussing this a bit:
http://lists.puremagic.com/pipermail/digitalmars-d/2011-April/101231.html and
the following posts

Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 26 2011
parent d-bugmail puremagic.com writes:

--- Comment #1 from Daniel Gibson <metalcaedes gmail.com> 2011-05-01 21:37:12
PDT ---
An additional comment: Seems like clear() *is* documented - not in the online
documentation but in TLDP on pages 187/188 (for classes) and 253/254 (for

It says: "You can invoke a struct object’s destructor explicitly by calling
clear(obj).", and the last code-example included
  auto obj1 = S("first object");
No new there, so it's even correct with the current clear implementation. 
It doesn't mention that clear doesn't work with "auto obj = new S("blah");".

And TLDP doesn't mention at all (at least on the pages the index lists for
"clear") that clear can be used with simple types and even pointers, setting
them to T.init.

So I'd suggest to only allow clear() for (class-) Objects, structs and pointers
to structs (in that case dereferencing the pointer and clearing the struct).
If something like clear() that is so generic that it works for *any* type is
needed, just add another function that does what clear() currently does.

Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 01 2011