www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5931] New: keyword new insists on calling a struct's (non-zero argument) constructor--in other words, it won't allow default initialization; also postblit this(this) constructor dosen't get called from "new <structname>(<struct_instance>)"

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5931

           Summary: keyword new insists on calling a struct's (non-zero
                    argument) constructor--in other words, it won't allow
                    default initialization; also postblit this(this)
                    constructor dosen't get called from "new
                    <structname>(<struct_instance>)"
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Mac OS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: ultimatemacfanatic gmail.com



2011-05-05 12:08:38 PDT ---
So I need to do this:

class Tokenizer
{
    File file;

    this(File f)
    {
        File f2; // default initialized

        // problem 1
        this.file = new File; // should pointer to return default initialized
File struct but compiler complains
        *this.file = f;

        // problem 2
        this.file = new File(f);  // this doesn't work either, notwithstanding
File has a this(this) post-blitter!
    }
}

unfortunately, on the line where I make the call to "new File", it gives me
this error:

Error: constructor std.stdio.File.this (string name, in const(char[])
stdioOpenmode = "rb") is not callable using argument types ()

Shouldn't I be able to allocate a default-initialized struct?  Or if not,
shouldn't it be allow to have empty-argument struct constructors?  
http://www.digitalmars.com/d/2.0/struct.html says empty parameter-list
constructors are not allowed for structs, but why not?  Can someone explain
this language decision to me and make a good argument for why it should not be
changed?

when I try "new File(f)" then I get this error message:

tokenizer.d(199): Error: constructor std.stdio.File.this (string name, in
const(char[]) stdioOpenmode = "rb") is not callable using argument types (File)
tokenizer.d(199): Error: cannot implicitly convert expression (file) of type
File to string

It seems to me that the post-blit constructor should be called automatically
when a struct  is "function-called" with an instance of the same struct as the
sole parameter like "new S(s_instance)"  Don't you agree?  You may think this
is a feature request, but when functionality is a departure from what one would
expect, I would tend to call that a bug instead.  :-)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 05 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5931




2011-05-05 19:55:08 PDT ---
This line above (5th line or so)

     File file;
should read File* file; in other words, the member <file> is supposed to be a pointer to File. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 05 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5931


kennytm gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kennytm gmail.com



Post-blit is only called when you override the whole structure, as in:

----------------------------------------
import std.stdio;

struct S {
    this(this) {
        writeln("postblit");
    }
}

void main() {
    S s;
    S t;
    s = t;    // <-- call postblit on s.
}
----------------------------------------

Pointer-assignment will *not* call post-blit as you have not blitted
(memcpy-ed) anything.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 06 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5931


Christopher the Magnificent <ultimatemacfanatic gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|keyword new insists on      |keyword new won't allow
                   |calling a struct's          |default initialization of a
                   |(non-zero argument)         |struct where it has a
                   |constructor--in other       |non-zero argument
                   |words, it won't allow       |constructor
                   |default initialization;     |
                   |also postblit this(this)    |
                   |constructor dosen't get     |
                   |called from "new            |
                   |<structname>(<struct_instan |
                   |ce>)"                       |



2011-05-06 12:32:02 PDT ---

 Post-blit is only called when you override the whole structure, as in:
 
 ----------------------------------------
 import std.stdio;
 
 struct S {
     this(this) {
         writeln("postblit");
     }
 }
 
 void main() {
     S s;
     S t;
     s = t;    // <-- call postblit on s.
 }
 ----------------------------------------
 
 Pointer-assignment will *not* call post-blit as you have not blitted
 (memcpy-ed) anything.
*Shouldn't* post-blit be invokable by calling <File(file)>? Wouldn't this be a desirable behavior? If not, how do I allocate a default-initialized File struct in the heap using <new> (so that I can follow that by overwriting the whole structure and get post-blitter to run)? what I'm taking about is this (this is what I want to do): //////////////////////////// import std.stdio; struct Tokenizer { File* file = null; void initFile(File f) { this.file = new File; // I want to allocate a new File struct and set it to File.init -- DOESN"T WORK! *this.file = f; // copy bits and then automatically call post-blit File.this(this) } } //////////////////////////// At the line above marked "DOESN'T WORK", the compiler refuses to allocate a new default-initialized File struct. This is a problem -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 06 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5931





 *Shouldn't* post-blit be invokable by calling <File(file)>?  Wouldn't this be a
 desirable behavior?
 
Sorry, got distracted by the 'this.file = new File(...)' part because of your 'File file;' :). No it should not call post-blit directly, because is possible to *declare* such a constructor. The problem is, should D define the implicitly-defined copy constructor which does: struct S { this(ref S s) { this = s; // implicitly calls the postblit } ... } ? [snip]
 At the line above marked "DOESN'T WORK", the compiler refuses to allocate a new
 default-initialized File struct.  This is a problem
This problem is the same as issue 4249. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 06 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5931






[snip]
 At the line above marked "DOESN'T WORK", the compiler refuses to allocate a new
 default-initialized File struct.  This is a problem
This problem is the same as issue 4249.
I mean issue 4247 -.- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 06 2011