Bug 20424 – A constructor with a value argument of the same type as being constructed should be an error

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-12-02T01:44:29Z
Last change time
2020-06-17T04:11:37Z
Assigned to
No Owner
Creator
Walter Bright

Comments

Comment #0 by bugzilla — 2019-12-02T01:44:29Z
extern(C) void puts(const char*); struct S { this(S) // should be a compile time error { puts("works fine"); } } void main() { S a; S b = S(a); } It should call itself recursively and crash. The fact that it appears to run successfully is also a bug. Copy constructors must take their first argument by reference. https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1018.md
Comment #1 by razvan.nitu1305 — 2019-12-02T10:54:52Z
This issue is invalid. That is not a copy constructor, it is a normal constructor so there is no threat of entering in infinite recursion. The reason why it works is that the compiler simply blitts the contents of a into the stack of the constructor. I don't see any problem with this.
Comment #2 by bugzilla — 2019-12-06T09:54:46Z
An object with a copy constructor cannot be blitted into place. (Such is not allowed in C++, either, and such constructors are rejected by the compiler.) There is no advantage to doing it anyway over passing by ref.
Comment #3 by andrei — 2019-12-09T15:30:32Z
This has been discussed and settled a long time ago.
Comment #4 by andrei — 2019-12-09T15:30:38Z
This has been discussed and settled a long time ago.
Comment #5 by razvan.nitu1305 — 2020-06-17T04:11:37Z
(In reply to Walter Bright from comment #2) > An object with a copy constructor cannot be blitted into place. (Such is not > allowed in C++, either, and such constructors are rejected by the compiler.) > > There is no advantage to doing it anyway over passing by ref. Yes there is. You may want to construct from an rvalue, therefore you cannot use a copy constructor since rvalue references are not yet implemented in the language (there is a switch but it is only half implemented). `this(S)` does exactly that. Of course, it is illegal to have both this(S) and this(ref S). We discussed this extensively in the DIP.