DMD 0.177 release
Pragma
ericanderton at yahoo.removeme.com
Tue Dec 12 07:29:55 PST 2006
Stewart Gordon wrote:
> Pragma wrote:
> <snip>
>> But I'd like to echo the other comments in this thread regarding
>> structs. IMO, we're not there yet. I think folks are looking for a
>> solution that does this:
>>
>> - A ctor like syntax for creating a new struct
>> - No more forced copy of the entire struct on creation
>
> What do you mean by this?
I'm glad you asked. :)
Static opCall() is not a ctor. It never was. People have been
clamoring to be able to use this() inside of a struct, much like they
can with classes and modules. But the desire here goes beyond mere
symmetry between type definitions.
The forced copy issue is something that is an artifact of emulating a
constructor for a struct. Take the standard approach for example:
struct Foo{
int a,b,c;
}
Foo f = {a:1, b:2, c:3};
Foo f = {1,2,3}; // more succinct version
So here we create a struct in place, and break encapsulation in the
process. What we really want is an opaque type, that has a little more
smarts on creation. Taking advantage of in/body/out would be nice too.
No problem, we'll just use opCall():
struct Foo{
int a,b,c;
static Foo opCall(int a,int b,int c){
Foo _this;
_this.a = a;
_this.b = b;
_this.c = c;
return _this;
}
}
Foo f = Foo(1,2,3);
That's better, but look at what's really happening here. Inlining and
compiler optimization aside, the 'constructor' here creates a Foo on the
stack which is then returned and *copied* to the destination 'f'.
To most, that won't ever seem like a problem. But for folks who are
working with Vector types or Matrix implementations, that's something to
scream about. In a nutshell, any struct wider than a register that is
populated in the 100's to 1000's is wasting cycles needlessly.
So that brings us to something like this:
struct Foo{
int a,b,c;
this(int a,int b,int c){
this.a = a;
this.b = b;
this.c = c;
}
}
Foo f = Foo(1,2,3);
Ambiguity aside, this fixes encapsulation, gives a familiar syntax, and
almost fixes the allocation issues. (see below)
>
>> - Something that is disambiguated from static opCall
> <snip>
>
> Do you mean that constructors for structs should have a notation
> distinct from S(...)?
>
Well, I think it's one of the reasons why we don't have ctors for
structs right now. The preferred syntax for a "struct ctor" would
probably be this:
S foo = S(a,b,c);
Which is indistinct from "static opCall". Throwing 'new' in there
wouldn't work either, since that would be a dynamic allocation:
S* foo = new S(a,b,c);
So that leaves us with "something else" that provides both a way to
invoke a ctor, yet allocates the data on the stack and doesn't force you
to create an additional copy:
S foo(a,b,c); // c++ style
S foo = stackalloc S(a,b,c); // alloca() style (in place of new)
S foo = new(stack) S(a,b,c): // another idea
--
- EricAnderton at yahoo
More information about the Digitalmars-d-announce
mailing list