Support implicit conversion between types

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Sep 4 16:20:28 PDT 2013


On Wed, Sep 04, 2013 at 04:07:28PM -0700, H. S. Teoh wrote:
> On Thu, Sep 05, 2013 at 01:04:30AM +0200, Kapps wrote:
> > On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:
> > >On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
> > >>On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:
> > >>
> > >>> D does not support implicit struct construction.
> > >>
> > >>That's what I knew.
> > >>
> > >>> Interestingly though, it *does* support it for functions taking
> > >>> classes:
> > >>>
> > >>> class Foo {
> > >>>          this(int i) {}
> > >>> }
> > >>>
> > >>> void foo(Foo f...) {}
> > >>>
> > >>> void main() {
> > >>>          foo(10);
> > >>> }
> > >>
> > >>WHAT? :) It even new's one?
> > >>
> > >>But it works only for the ellipsis.
> > >>
> > >>I wonder why the discrepancy...
> > >[...]
> > >
> > >Whoa. I never knew about this! It's ... I don't know what to say.  It
> > >seems to be a cool feature, but it's also ... so scary. Implicit
> > >new's just leaves a lump in my throat. Is this an actual, intentional
> > >feature??!
> > >
> > >
> > >T
> > 
> > It, in theory, doesn't allocate memory:
> > "An implementation may construct the object or array instance on the
> > stack. Therefore, it is an error to refer to that instance after the
> > variadic function has returned"
> 
> That's even more scary. So the object implicitly constructed in this way
> is put on the *stack* instead of the heap, and becomes invalid after the
> function returns? That's just a minefield of pitfalls waiting to
> happen...
[...]

Hmm.  I experimented with this "feature", and found some interesting
quirks:

	void foo(Foo f...) {...}

can only be called with the same arguments as Foo's ctor, and 'f' inside
the function body refers to the *single* class instance implicitly
constructed.  The object is actually allocated on the heap, even though
the class reference is on the stack (perfectly normal). So this syntax
appears to be some kind of surrogate ctor syntax, in which foo() acts as
a surrogate ctor, getting the constructed object as a parameter and
possibly modifying it or returning something else in its place.

I can see where this might be useful, but I'm confused by the choice of
syntax. This isn't a true variadic function at all; it's a ctor wrapper?
Why was this syntax chosen?

I'm really puzzled now.


T

-- 
One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie. -- The Silicon Valley Tarot


More information about the Digitalmars-d-learn mailing list