pass-by-ref semantics for structs (was Deque impl.)

Dmitry Olshansky dmitry.olsh at gmail.com
Thu Jan 31 11:34:28 PST 2013


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

Basically @dsiable this() is optional, but I like to help user avoid bugs.

>
> import runtime;
>
> mixin(declareExternInitZPointer!S);
>
> static this()
> {
>      A a = new A;
>      a.x = 100;
>      S s =  S(100, a);
>      rtSetDefaultHeapInitializer(s);
>      rtSetDefaultStackInitializer(s, mixin(passExternInitZPointer!S));
> }
> ----------------------
>
> Where runtime module is http://dpaste.dzfl.pl/40b59a5d
>
> This does not fully replace default ctor, since all instances of S are
> affected.


-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list