31-Jan-2013 23:54, Robert burner Schadek пишет:
On 01/31/2013 08:34 PM, Dmitry Olshansky wrote:
31-Jan-2013 23:32, Maxim Fomin пишет:
On Thursday, 31 January 2013 at 19:17:56 UTC, Dmitry Olshansky wrote:
31-Jan-2013 19:21, Andrei Alexandrescu пишет:
On 1/31/13 10:18 AM, Steven Schveighoffer wrote:
On Thu, 31 Jan 2013 10:12:53 -0500, Andrei Alexandrescu
As far as I can tell classes have the same problem.
Nope.
void foo(someclass aa, int x, int y)
{
aa[x] = y;
}
void main()
{
someclass aa;
foo(aa, 1, 2); // segfault
...
}
We could easily arrange things to segfault just the same with a
struct-based implementation.
Structs are quite borked in this regard e.g. without extra efforts the
following:
somclass aa = someclass();
foor(aa, 1, 2); // segfault, surprize someclass() is someclass.init
The current workaround I find the most sensible is:
- @disable this();
- make all constructors private
- define opCall and forward it to private constructors. 0-arg versions
have to pass dummy and/or default values to get struct constructed
- automate this boilerplate until something in language is fixed? :)
The advantage is that the following is illegal:
someclass aa;
and the following works as expected:
auto aa = someclass(); //create empty container damn it!
If desired default struct value is constant for all instances of that
struct, there is another workaround by changing init values:
-------------------
import std.stdio;
class A { int x = 5; }
struct S { int x = 5; A a; }
void main()
{
S s; // defaults to preallocated a, a is not null
assert(S.x is 100 && s.a !is null && s.a.x is 100);
}
This is fine except that it doesn't solve the problem of:
Container a = Container(); //should be empty container, not illegal
null-container
Just use a payload struct and check whether that is null before every
operation.
Lazy evaluation, great. Except that is a useless opcode per every
operation with container + keep in in mind the problem:
void func(cont a)
{
//if a was empty and we go with lazy-initialization
// then the outside cont is not updated
a.insert(...);
}
void main()
{
...
cont x;
...
//this could be non-trivial code that
//may or may not touch x in all path
func(x);
...
}
--
Dmitry Olshansky