Bug 5931 – keyword new won't allow default initialization of a struct where it has a non-zero argument constructor

Status
RESOLVED
Resolution
WONTFIX
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2011-05-05T12:08:38Z
Last change time
2018-05-05T13:15:28Z
Assigned to
No Owner
Creator
Christopher the Magnificent

Comments

Comment #0 by ultimatemacfanatic — 2011-05-05T12:08:38Z
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. :-)
Comment #1 by ultimatemacfanatic — 2011-05-05T19:55:08Z
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.
Comment #2 by kennytm — 2011-05-06T01:46:03Z
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.
Comment #3 by ultimatemacfanatic — 2011-05-06T12:32:02Z
(In reply to comment #2) > 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
Comment #4 by kennytm — 2011-05-06T12:47:28Z
(In reply to comment #3) > *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.
Comment #5 by kennytm — 2011-05-06T12:48:43Z
(In reply to comment #4) > (In reply to comment #3) [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 -.-
Comment #6 by johannes.loher — 2018-05-05T13:15:28Z
The first problem mentioned has been solved since 2.063. The second problem is still present, error message of 2.080.0: main.d(16): Error: none of the overloads of this are callable using argument types (File), candidates are: /usr/include/dlang/dmd/std/stdio.d(387): std.stdio.File.this(shared(_IO_FILE)* handle, string name, uint refs = 1u, bool isPopened = false) /usr/include/dlang/dmd/std/stdio.d(425): std.stdio.File.this(string name, const(char[]) stdioOpenmode = "rb") /usr/include/dlang/dmd/std/stdio.d(443): std.stdio.File.__ctor(R1, R2)(R1 name) if (isInputRange!R1 && isSomeChar!(ElementEncodingType!R1)) /usr/include/dlang/dmd/std/stdio.d(451): std.stdio.File.__ctor(R1, R2)(R1 name, R2 mode) if (isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) && isInputRange!R2 && isSomeChar!(ElementEncodingType!R2)) The reason is in general, that you can't call postblits as if they were constructors (`File file; auto f = File(file);` also does not work). However, it seems that postblits will probably be replaced by some form of copy constructor, so this might even resolve this issue. I will close this for now. If you really want this feature, please submit a new issue as an enhancement request.