View mode: basic / threaded / horizontal-split · Log in · Help
October 04, 2012
T.init and @disable this
I'm trying to find out the exact semantics of

@disable this();

It is not well documented, and the fact that it is (supposedly) 
buggy makes it really confusing.

My understanding is that it "merely" makes it illegal to default 
initialization your type: You, the developer, have to specify the 
initial value.

//----
T t; //initializer required for type
//----
Which means, you, the developper, must explicitly choose an 
initial value.

However, DOES or DOES NOT this remain legal?
//----
T t = T.init; //Fine: You chose the initializer T.init
//----

Keep in mind it is not possible to make "T.init" itself 
disappear, because nothing can be constructed if T.init is not 
first memcopied onto the object, before calling any constructor 
proper.

I think this should be legal, because you, the developer, is 
asking for it, just the same way one can write "T t = void".

Making it illegal would pretty much make T unmoveable, 
un-emplaceable, un-initializeable on un-initialized memmory, and 
would probably break more than one function/trait which uses 
"T.init"

Feedback?
October 04, 2012
Re: T.init and @disable this
On Thursday, October 04, 2012 10:18:14 monarch_dodra wrote:
> Making it illegal would pretty much make T unmoveable,
> un-emplaceable, un-initializeable on un-initialized memmory,

That's kind of the point. If that's not what you want, don't disable init.

> and
> would probably break more than one function/trait which uses
> "T.init"

Which is a definite downside to the whole disabling init idea.

As for T.init and constructors, it should be perfectly possible to initialize 
the object to what T.init would be prior to construction without making T.init 
available at all.

- Jonathan M Davis
October 04, 2012
Re: T.init and @disable this
On Thursday, 4 October 2012 at 09:25:01 UTC, Jonathan M Davis 
wrote:
> On Thursday, October 04, 2012 10:18:14 monarch_dodra wrote:
>> Making it illegal would pretty much make T unmoveable,
>> un-emplaceable, un-initializeable on un-initialized memmory,
>
> That's kind of the point. If that's not what you want, don't 
> disable init.

Hum... I had never actually thought of it that way!

>> and
>> would probably break more than one function/trait which uses
>> "T.init"
>
> Which is a definite downside to the whole disabling init idea.
>
> As for T.init and constructors, it should be perfectly possible 
> to initialize
> the object to what T.init would be prior to construction 
> without making T.init
> available at all.
>
> - Jonathan M Davis

Good point too.
October 04, 2012
Re: T.init and @disable this
On 10/4/12, monarch_dodra <monarchdodra@gmail.com> wrote:
> I'm trying to find out the exact semantics of
>
> @disable this();

Also this still works:

struct Foo
{
   @disable this();
}

void main()
{
   Foo foo = Foo();
}

I really don't know why though.. Isn't this a bug? A workaround in
user-code is defining a disabled static opCall:

struct Foo
{
   @disable this();
   @disable static void opCall();
}
October 04, 2012
Re: T.init and @disable this
On Thursday, 4 October 2012 at 17:37:58 UTC, Andrej Mitrovic 
wrote:
> On 10/4/12, monarch_dodra <monarchdodra@gmail.com> wrote:
>> I'm trying to find out the exact semantics of
>>
>> @disable this();
>
> Also this still works:
>
> struct Foo
> {
>     @disable this();
> }
>
> void main()
> {
>     Foo foo = Foo();
> }
>
> I really don't know why though.. Isn't this a bug? A workaround 
> in
> user-code is defining a disabled static opCall:
>
> struct Foo
> {
>     @disable this();
>     @disable static void opCall();
> }

http://d.puremagic.com/issues/show_bug.cgi?id=8703
October 04, 2012
Re: T.init and @disable this
2012/10/4 monarch_dodra <monarchdodra@gmail.com>:
> I'm trying to find out the exact semantics of
>
> @disable this();
>
> It is not well documented, and the fact that it is (supposedly) buggy makes
> it really confusing.
>
> My understanding is that it "merely" makes it illegal to default
> initialization your type: You, the developer, have to specify the initial
> value.
>
> //----
> T t; //initializer required for type
> //----
> Which means, you, the developper, must explicitly choose an initial value.
>
> However, DOES or DOES NOT this remain legal?
> //----
> T t = T.init; //Fine: You chose the initializer T.init
> //----
>
> Keep in mind it is not possible to make "T.init" itself disappear, because
> nothing can be constructed if T.init is not first memcopied onto the object,
> before calling any constructor proper.
>
> I think this should be legal, because you, the developer, is asking for it,
> just the same way one can write "T t = void".

I think that T.init is legal even if T has just only @disable this()
constructor. If not,
> Making it illegal would pretty much make T unmoveable, un-emplaceable,
> un-initializeable on un-initialized memmory, and would probably break more
> than one function/trait which uses "T.init"

But, I also agree that T.init _sometimes_ *unsafe*.
1) If T has @disable this(), T.init will returns an object which just
initialized (== the value itself is never undefined), but not
constructed (might be logically invalid object).
2) If T is nested struct, it's frame pointer is always null. It might
cause access violation by its member function call.

I came up with just now: The use of such unsafe T.init should be
allowed only inside @system/@trusted functions.
I think it is acceptable limitation.

Thoughts?

Kenji Hara
October 05, 2012
Re: T.init and @disable this
Le 04/10/2012 10:18, monarch_dodra a écrit :
> I'm trying to find out the exact semantics of
>
> @disable this();
>
> It is not well documented, and the fact that it is (supposedly) buggy
> makes it really confusing.
>
> My understanding is that it "merely" makes it illegal to default
> initialization your type: You, the developer, have to specify the
> initial value.
>
> //----
> T t; //initializer required for type
> //----
> Which means, you, the developper, must explicitly choose an initial value.
>
> However, DOES or DOES NOT this remain legal?
> //----
> T t = T.init; //Fine: You chose the initializer T.init
> //----
>
> Keep in mind it is not possible to make "T.init" itself disappear,
> because nothing can be constructed if T.init is not first memcopied onto
> the object, before calling any constructor proper.
>
> I think this should be legal, because you, the developer, is asking for
> it, just the same way one can write "T t = void".
>
> Making it illegal would pretty much make T unmoveable, un-emplaceable,
> un-initializeable on un-initialized memmory, and would probably break
> more than one function/trait which uses "T.init"
>
> Feedback?

Making T.init unsafe in this case should be enough.
October 06, 2012
Re: T.init and @disable this
On 10/4/12 7:33 AM, kenji hara wrote:
> But, I also agree that T.init _sometimes_ *unsafe*.
> 1) If T has @disable this(), T.init will returns an object which just
> initialized (== the value itself is never undefined), but not
> constructed (might be logically invalid object).
> 2) If T is nested struct, it's frame pointer is always null. It might
> cause access violation by its member function call.
>
> I came up with just now: The use of such unsafe T.init should be
> allowed only inside @system/@trusted functions.
> I think it is acceptable limitation.
>
> Thoughts?

I think we should go back to the rationale for introducing @disable. The 
most important motivating examples were:

1. Defining NonNull references

2. Defining objects that are movable but not copyable

For NonNull references, the existence of an usable T.init would be a 
definite problem because it would suddenly allow the existence of, well, 
a null reference.

For (2) there may also be breakage, although more subtle: uncopyable 
objects are often associated with carefully-guarded resources (e.g. 
mutex locks) and shouldn't exist without special creation.

However, T.init is good to have as an always available value inside 
static code that tests e.g. for capabilities.

(There's been a long-standing similar problem in C++ as well.)

A possible solution is to allow T.init for uncopyable types as an 
unresolved reference: code can use it symbolically, but if it tries to 
actually do things with it at runtime that would be a link-time error.

Another solution would be to define T.init for uncopyable types as 
function that just throws if ever called.

Thoughts?


Andrei
October 06, 2012
Re: T.init and @disable this
On Saturday, October 06, 2012 02:54:23 Andrei Alexandrescu wrote:
> A possible solution is to allow T.init for uncopyable types as an
> unresolved reference: code can use it symbolically, but if it tries to
> actually do things with it at runtime that would be a link-time error.

This sounds like a great solution. Being able to disallow the init property 
where appropriate but still be able to use it with compile-time reflection 
would be fantastic. The issues with compile-time checks are the biggest 
problem that I've had with the idea of disabling init.

> Another solution would be to define T.init for uncopyable types as
> function that just throws if ever called.

A linker problem would be better than throwing IMHO.

Regardless, we need to better sort out how disabling init works. It was my 
understanding that the correct way to do it was to do

@disable this();

but apparently that's in dispute (at least, Kenji doesn't seem to think that 
that's supposed to disable the init property), and it doesn't actually work.

- Jonathan M Davis
October 06, 2012
Re: T.init and @disable this
2012/10/6 Jonathan M Davis <jmdavisProg@gmx.com>:
> Regardless, we need to better sort out how disabling init works. It was my
> understanding that the correct way to do it was to do
>
> @disable this();
>
> but apparently that's in dispute (at least, Kenji doesn't seem to think that
> that's supposed to disable the init property), and it doesn't actually work.

My argue is simple: If your argument is proper behavior, you never
move NonNull object.

Kenji Hara
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home