November 13, 2006
Sean Kelly wrote:
> Tomas Lindquist Olsen wrote:
>> Another argument for using 'auto' for ATI can be making it consistent with how it currently works for classes in DMD:
>>
>> class A
>> {
>>     static
>>     {
>>         auto x = 2;
>>         auto y = 42;
>>     }
>>     auto z = 27;
>> }
>>
>> This works. x and y are static!
> 
> I think this works everywhere, as you're free to chain storage classes to your heart's delight:
> 
>     // what is this??
>     auto const static const static auto x = 5;
> 
> 
> Sean

That does not work:
scopetest.d(29): redundant storage class 'const'
scopetest.d(29): redundant storage class 'static'
scopetest.d(29): redundant storage class 'auto'
November 13, 2006
Tomas Lindquist Olsen wrote:
> Sean Kelly wrote:
>> Tomas Lindquist Olsen wrote:
>>> Another argument for using 'auto' for ATI can be making it consistent with how it currently works for classes in DMD:
>>>
>>> class A
>>> {
>>>     static
>>>     {
>>>         auto x = 2;
>>>         auto y = 42;
>>>     }
>>>     auto z = 27;
>>> }
>>>
>>> This works. x and y are static!
>>
>> I think this works everywhere, as you're free to chain storage classes to your heart's delight:
>>
>>     // what is this??
>>     auto const static const static auto x = 5;
>>
>>
>> Sean
> 
> That does not work:
> scopetest.d(29): redundant storage class 'const'
> scopetest.d(29): redundant storage class 'static'
> scopetest.d(29): redundant storage class 'auto'

Oh, so you can just do:

    auto const static x = 5;

Could be worse, I suppose.

Sean
November 13, 2006
Sean Kelly wrote:
> Tomas Lindquist Olsen wrote:
>> Sean Kelly wrote:
>>> Tomas Lindquist Olsen wrote:
>>>> Another argument for using 'auto' for ATI can be making it consistent with how it currently works for classes in DMD:
>>>>
>>>> class A
>>>> {
>>>>     static
>>>>     {
>>>>         auto x = 2;
>>>>         auto y = 42;
>>>>     }
>>>>     auto z = 27;
>>>> }
>>>>
>>>> This works. x and y are static!
>>>
>>> I think this works everywhere, as you're free to chain storage classes to your heart's delight:
>>>
>>>     // what is this??
>>>     auto const static const static auto x = 5;
>>>
>>>
>>> Sean
>>
>> That does not work:
>> scopetest.d(29): redundant storage class 'const'
>> scopetest.d(29): redundant storage class 'static'
>> scopetest.d(29): redundant storage class 'auto'
> 
> Oh, so you can just do:
> 
>     auto const static x = 5;
> 
> Could be worse, I suppose.
> 
> Sean

It is definitely a bit weird. I would like to see all combinations of these fail. they dont make any sense together. all provide ATI if present. the only problem I can see is if you want to put a constant inside a static block. but maybe that is handled differently?

IMHO this would make sense:

Invalid:
---------
static const x = 5;
const static x = 5;
const
{
	static x = 5;
}
any combination of auto and const/static

Valid:
---------
const x = 5;
static x = 5;
static
{
	const x = 5;
	auto x = 5;
}
const
{
	auto x = 5;
}

Did I forget any?
November 13, 2006
Tomas Lindquist Olsen wrote:
> Sean Kelly wrote:
> 
> It is definitely a bit weird. I would like to see all combinations of these fail. they dont make any sense together. all provide ATI if present. the only problem I can see is if you want to put a constant inside a static block. but maybe that is handled differently?
> 
> IMHO this would make sense:
> 
> Invalid:
> ---------
> static const x = 5;

What's wrong with static and const together?
One says this is actually store with globals not on the stack, the other says the value isn't going to change.  Nothing inconsistent about having those two together.
November 13, 2006
Sean Kelly wrote:
> And most seem to favor the addition of a new keyword, probably 'scope' somewhere in the declaration.  popular form seems to be:
> 
>     scope MyClass c = new MyClass(); // scoped decl
>     auto scope c    = new MyClass(); // inferred scoped decl
> 
> Is this correct so far?

Yes.

> And if so, I'd like to re-iterate my concerns about such a syntax:
> 
> With the above, the 'scope' identifier is associated with the reference, not the data.  Thus, it would be equivalent to:
> 
>     MyClass c = new MyClass();
>     scope(exit) delete c;

Yes.

> This raises a host of issues if such references are reassignable, and in the worst case would mean that scoped data could not be allocated on the stack unless the compiler had some form of escape detection.  For example:
> 
>     scope MyClass c = new MyClass();
>     c = new MyClass();
>     MyClass d = c;
>     return d;
> 
> Here, we have a new instance of MyClass that should be destroyed on scope exit (by my understanding).  However, c is reassigned to a new instance of MyClass before this occurs.  The current result is that the new instance is destroyed instead of the old one and the old one will remain in memory until the next GC collection.  Also, 'd' will return a reference to data that no longer exists since it will be destroyed when 'c' goes out of scope.

That's right. It isn't much different from the C++ code:

	MyClass c();
	MyClass& d = c;
	return d;		// Oops!

> Even worse:
> 
>     scope MyClass c = new MyClass();
>     scope MyClass d = c;
> 
> Here, we have two scoped references both referring to the same piece of data, which results in a double-deletion.  Therefore, to be implemented correctly and safely, such references must uniquely refer to the underlying data, much like C++'s auto_ptr.

Right. I hope to improve the static analysis to detect and issue compile time errors for such cases.

> Finally:
> 
>     scope int* i = new int;
> 
> What happens here?  Will the compiler disallow the use of 'scope' on non-class types, will 'i' be deleted on scope exit, or will 'scope' simply be ingored?

scope is ignored for non-reference types.

> If we are truly to use the 'scope' keyword for RAII objects, I humbly request that the data be flagged instead of the reference.  Here are two suggestions for syntax:
> 
>     MyClass c = scope MyClass();
>     MyClass c = new(scope) MyClass();
> 
> Both would allow data to be allocated on the stack without escape detection (or an assumption that the user isn't being evil), and the latter is even almost identical to how alloca is used now.  I dislike that both would make class allocation semantically different from concrete type allocation, but anything is better than associating 'scope' with the reference itself, for the reasons illustrated above.

It's a good idea, but there's currently no way to flag data itself in this way.
November 13, 2006
Walter Bright wrote:
> Sean Kelly wrote:
> 
>> If we are truly to use the 'scope' keyword for RAII objects, I humbly request that the data be flagged instead of the reference.  Here are two suggestions for syntax:
>>
>>     MyClass c = scope MyClass();
>>     MyClass c = new(scope) MyClass();
>>
>> Both would allow data to be allocated on the stack without escape detection (or an assumption that the user isn't being evil), and the latter is even almost identical to how alloca is used now.  I dislike that both would make class allocation semantically different from concrete type allocation, but anything is better than associating 'scope' with the reference itself, for the reasons illustrated above.
> 
> It's a good idea, but there's currently no way to flag data itself in this way.

Hrm... so the compiler would have to do something like generate a dummy variable referencing the class instance and act on that instead, and count on the optimizer to throw away the dummy variable when 'c' isn't reassigned in the enclosing scope.  I suppose that could be a bit confusing when debugging... and some might complain about the unpredictable stack frame size or some such.  Well darn :-)


Sean
November 13, 2006
Bill Baxter wrote:
> Tomas Lindquist Olsen wrote:
>> Sean Kelly wrote:
>>
>> It is definitely a bit weird. I would like to see all combinations of these fail. they dont make any sense together. all provide ATI if present. the only problem I can see is if you want to put a constant inside a static block. but maybe that is handled differently?
>>
>> IMHO this would make sense:
>>
>> Invalid:
>> ---------
>> static const x = 5;
> 
> What's wrong with static and const together?
> One says this is actually store with globals not on the stack, the other says the value isn't going to change.  Nothing inconsistent about having those two together.
Does it really make sense to have the programmer decide this distinction? A global const will definitely have static storage. But why  not let the compiler decide?

I just don't see where having this choice is useful!
November 13, 2006
Tomas Lindquist Olsen wrote:
> Bill Baxter wrote:
>> Tomas Lindquist Olsen wrote:
>>> Sean Kelly wrote:
>>>
>>> It is definitely a bit weird. I would like to see all combinations of these fail. they dont make any sense together. all provide ATI if present. the only problem I can see is if you want to put a constant inside a static block. but maybe that is handled differently?
>>>
>>> IMHO this would make sense:
>>>
>>> Invalid:
>>> ---------
>>> static const x = 5;
>>
>> What's wrong with static and const together?
>> One says this is actually store with globals not on the stack, the other says the value isn't going to change.  Nothing inconsistent about having those two together.
> Does it really make sense to have the programmer decide this distinction? A global const will definitely have static storage. But why  not let the compiler decide?
> 
> I just don't see where having this choice is useful!

In a function?
In a class?

--bb
November 14, 2006
Bill Baxter wrote:
> Tomas Lindquist Olsen wrote:
>> Bill Baxter wrote:
>>> Tomas Lindquist Olsen wrote:
>>>> Sean Kelly wrote:
>>>>
>>>> It is definitely a bit weird. I would like to see all combinations of these fail. they dont make any sense together. all provide ATI if present. the only problem I can see is if you want to put a constant inside a static block. but maybe that is handled differently?
>>>>
>>>> IMHO this would make sense:
>>>>
>>>> Invalid:
>>>> ---------
>>>> static const x = 5;
>>>
>>> What's wrong with static and const together?
>>> One says this is actually store with globals not on the stack, the other says the value isn't going to change.  Nothing inconsistent about having those two together.
>> Does it really make sense to have the programmer decide this distinction? A global const will definitely have static storage. But why  not let the compiler decide?
>>
>> I just don't see where having this choice is useful!
> 
> In a function?
> In a class?
> 
> --bb

a static in a class is well defined. so is a const. for me 'static const' reads as having the 'static' redundant. a 'const' in D is by definition static. It cannot change, as only a compile-time constant will qualify, and thus will be the same to all classes of whatever reads it.
a function 'const' is very much the same. I fail to come up with a scenario where choosing the storage model for a constant makes any sense!
Can you post an example of why we need 'static const' ?
November 14, 2006
Tomas Lindquist Olsen wrote:
> Can you post an example of why we need 'static const' ?

int foo(int x)
{
    static const i = x;	// error, x is not const
    const j = x;	// ok, j is const for duration of foo() call
}