Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
September 05, 2007 'in' storage class | ||||
---|---|---|---|---|
| ||||
'in' is equivalent to final const scope. I can't understand the point of making the variable 'final' if it's already 'const' ? |
September 05, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Funog | Funog wrote:
> 'in' is equivalent to final const scope.
> I can't understand the point of making the variable 'final' if it's already 'const' ?
>
In D 2.0, 'final' represents 'head-const', while 'const' means 'tail-const'. This makes a difference when talking about arrays: 'final' will make the array reference itself const, so you can't change it to refer to a different array, while 'const' makes the contents of the array const - you can change the variable to point to another array or slice, but you can't edit any array through that reference.
Thanks,
Nathan Reed
|
September 05, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nathan Reed | Nathan Reed Wrote:
> Funog wrote:
> > 'in' is equivalent to final const scope.
> > I can't understand the point of making the variable 'final' if it's already 'const' ?
> >
>
> In D 2.0, 'final' represents 'head-const', while 'const' means 'tail-const'. This makes a difference when talking about arrays: 'final' will make the array reference itself const, so you can't change it to refer to a different array, while 'const' makes the contents of the array const - you can change the variable to point to another array or slice, but you can't edit any array through that reference.
>
> Thanks,
> Nathan Reed
It's true for const(uint[]) or const(uint)[], but we are talking of const uint[], which forbid any change.
void testFinal(final int[] foo)
{
foo[0] = 10; //OK
foo = new int[20]; //ERROR
}
void testConst(const int[] foo)
{
foo[0] = 10; //ERROR
foo = new int[20]; //ERROR
}
void testFinalConst(final const int[] foo)
{
foo[0] = 10; //ERROR
foo = new int[20]; //ERROR
}
So what is the difference between 'const' and 'final const' ?
|
September 05, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Funog | Funog wrote:
> void testFinal(final int[] foo)
> {
> foo[0] = 10; //OK
> foo = new int[20]; //ERROR
> }
> void testConst(const int[] foo)
> {
> foo[0] = 10; //ERROR
> foo = new int[20]; //ERROR
> }
> void testFinalConst(final const int[] foo)
> {
> foo[0] = 10; //ERROR
> foo = new int[20]; //ERROR
> }
>
>
> So what is the difference between 'const' and 'final const' ?
>
I suppose there's no practical difference in that case since you're using the transitive const. Note that final const(int)[] foo is different from const(int)[] foo though.
Thanks,
Nathan Reed
|
September 05, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nathan Reed | Nathan Reed Wrote:
> Funog wrote:
> > void testFinal(final int[] foo)
> > {
> > foo[0] = 10; //OK
> > foo = new int[20]; //ERROR
> > }
> > void testConst(const int[] foo)
> > {
> > foo[0] = 10; //ERROR
> > foo = new int[20]; //ERROR
> > }
> > void testFinalConst(final const int[] foo)
> > {
> > foo[0] = 10; //ERROR
> > foo = new int[20]; //ERROR
> > }
> >
> >
> > So what is the difference between 'const' and 'final const' ?
> >
>
> I suppose there's no practical difference in that case since you're using the transitive const. Note that final const(int)[] foo is different from const(int)[] foo though.
>
> Thanks,
> Nathan Reed
I agree... But then, what is the point of having 'in' equivalent to 'final const scope' rather than just 'const scope' ?
|
September 05, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Funog | Funog Wrote:
> Nathan Reed Wrote:
>
> > Funog wrote:
> > > void testFinal(final int[] foo)
> > > {
> > > foo[0] = 10; //OK
> > > foo = new int[20]; //ERROR
> > > }
> > > void testConst(const int[] foo)
> > > {
> > > foo[0] = 10; //ERROR
> > > foo = new int[20]; //ERROR
> > > }
> > > void testFinalConst(final const int[] foo)
> > > {
> > > foo[0] = 10; //ERROR
> > > foo = new int[20]; //ERROR
> > > }
> > >
> > >
> > > So what is the difference between 'const' and 'final const' ?
> > >
> >
> > I suppose there's no practical difference in that case since you're using the transitive const. Note that final const(int)[] foo is different from const(int)[] foo though.
> >
> > Thanks,
> > Nathan Reed
>
>
>
> I agree... But then, what is the point of having 'in' equivalent to 'final const scope' rather than just 'const scope' ?
>
The difference is easier for me to grasp when talking about class references than arrays.
class Foo { int bar; }
final Foo baz;
baz.bar = 5; // Okay
baz = quux; // Illegal
const Foo quux; // Equivilent, I _think_ to const(Foo) quux;
quux.bar = 5; // Illegal
quux = baz; //Okay
In other words, for a class reference, head-const (final) means that the reference can't be changed to point to something else, but the data can be changed. Head-const is not transitive. Tail-const (const or invariant, in the case of a class reference) means that the thing being pointed to cannot be changed, but the reference can be.
This is generalized to array references and pointers.
|
September 06, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Fraser | Robert Fraser Wrote:
> Funog Wrote:
>
> > Nathan Reed Wrote:
> >
> > > Funog wrote:
> > > > void testFinal(final int[] foo)
> > > > {
> > > > foo[0] = 10; //OK
> > > > foo = new int[20]; //ERROR
> > > > }
> > > > void testConst(const int[] foo)
> > > > {
> > > > foo[0] = 10; //ERROR
> > > > foo = new int[20]; //ERROR
> > > > }
> > > > void testFinalConst(final const int[] foo)
> > > > {
> > > > foo[0] = 10; //ERROR
> > > > foo = new int[20]; //ERROR
> > > > }
> > > >
> > > >
> > > > So what is the difference between 'const' and 'final const' ?
> > > >
> > >
> > > I suppose there's no practical difference in that case since you're using the transitive const. Note that final const(int)[] foo is different from const(int)[] foo though.
> > >
> > > Thanks,
> > > Nathan Reed
> >
> >
> >
> > I agree... But then, what is the point of having 'in' equivalent to 'final const scope' rather than just 'const scope' ?
> >
>
> The difference is easier for me to grasp when talking about class references than arrays.
>
> class Foo { int bar; }
>
> final Foo baz;
> baz.bar = 5; // Okay
> baz = quux; // Illegal
>
> const Foo quux; // Equivilent, I _think_ to const(Foo) quux;
> quux.bar = 5; // Illegal
> quux = baz; //Okay
>
It isn't... Both lines are illegal. quux = baz is legal for const(Foo) quux.
If nobody can tell the difference between "const scope" and "in" ( = final const scope ), should we report it as a bug ? xD
|
September 06, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Funog | Funog wrote:
> Robert Fraser Wrote:
>
>> Funog Wrote:
>>
>>> Nathan Reed Wrote:
>>>
>>>> Funog wrote:
>>>>> void testFinal(final int[] foo)
>>>>> {
>>>>> foo[0] = 10; //OK
>>>>> foo = new int[20]; //ERROR
>>>>> }
>>>>> void testConst(const int[] foo)
>>>>> {
>>>>> foo[0] = 10; //ERROR
>>>>> foo = new int[20]; //ERROR
>>>>> }
>>>>> void testFinalConst(final const int[] foo)
>>>>> {
>>>>> foo[0] = 10; //ERROR
>>>>> foo = new int[20]; //ERROR
>>>>> }
>>>>>
>>>>>
>>>>> So what is the difference between 'const' and 'final const' ?
>>>>>
>>>> I suppose there's no practical difference in that case since you're using the transitive const. Note that final const(int)[] foo is different from const(int)[] foo though.
>>>>
>>>> Thanks,
>>>> Nathan Reed
>>>
>>>
>>> I agree... But then, what is the point of having 'in' equivalent to 'final const scope' rather than just 'const scope' ?
>>>
>> The difference is easier for me to grasp when talking about class references than arrays.
>>
>> class Foo { int bar; }
>>
>> final Foo baz;
>> baz.bar = 5; // Okay
>> baz = quux; // Illegal
>>
>> const Foo quux; // Equivilent, I _think_ to const(Foo) quux;
>> quux.bar = 5; // Illegal
>> quux = baz; //Okay
>>
>
>
> It isn't... Both lines are illegal. quux = baz is legal for const(Foo) quux.
> If nobody can tell the difference between "const scope" and "in" ( = final const scope ), should we report it as a bug ? xD
>
If I understand stuff right, "quux = baz;" should be legal. Use of quux thereafter, including reassigning quux, does not invalidate baz's use of final. I have not tested this with a compiler, of course...
|
September 08, 2007 Re: 'in' storage class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Funog | Funog wrote:
> Robert Fraser Wrote:
>
>> Funog Wrote:
>>
>> > Nathan Reed Wrote:
>> >
>> > > Funog wrote:
>> > > > void testFinal(final int[] foo)
>> > > > {
>> > > > foo[0] = 10; //OK
>> > > > foo = new int[20]; //ERROR
>> > > > }
>> > > > void testConst(const int[] foo)
>> > > > {
>> > > > foo[0] = 10; //ERROR
>> > > > foo = new int[20]; //ERROR
>> > > > }
>> > > > void testFinalConst(final const int[] foo)
>> > > > {
>> > > > foo[0] = 10; //ERROR
>> > > > foo = new int[20]; //ERROR
>> > > > }
>> > > >
>> > > >
>> > > > So what is the difference between 'const' and 'final const' ?
>> > > >
>> > >
>> > > I suppose there's no practical difference in that case since you're using the transitive const. Note that final const(int)[] foo is different from const(int)[] foo though.
>> > >
>> > > Thanks,
>> > > Nathan Reed
>> >
>> >
>> >
>> > I agree... But then, what is the point of having 'in' equivalent to 'final const scope' rather than just 'const scope' ?
>> >
>>
>> The difference is easier for me to grasp when talking about class references than arrays.
>>
>> class Foo { int bar; }
>>
>> final Foo baz;
>> baz.bar = 5; // Okay
>> baz = quux; // Illegal
>>
>> const Foo quux; // Equivilent, I _think_ to const(Foo) quux;
>> quux.bar = 5; // Illegal
>> quux = baz; //Okay
>>
>
>
> It isn't... Both lines are illegal. quux = baz is legal for const(Foo) quux.
> If nobody can tell the difference between "const scope" and "in" ( = final const scope ), should we report it as a bug ? xD
>
I tried this:
---
void f(const int* p)
{
int y = 9;
*p = 7; // line 5
p = &y; // line 6
}
void main()
{
int x = 5;
f(&x);
}
---
dmd -run inargs
inargs.d(5): Error: *p is not mutable
inargs.d(6): variable inargs.f.p cannot modify final/const/invariant variable 'p'
Adding 'final' doesn't change anything. So it would seem that this feature isn't finalized yet. 'scope' doesn't seem to work either. If I use 'final const(int)*' instead, I get the same errors.
Barring optimizations, a function's arguments are not known a compile-time. So I don't know if giving them the const or invariant storage class makes much sense. Maybe the idea was that const in a parameter list would always mean const as a type constructor. For other declarations, 'final const(int)*' allows run-time (by a constructor) initialization, while 'const int*' does not. So maybe the latter one should be disallowed in parameter lists.
|
Copyright © 1999-2021 by the D Language Foundation