www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - 'in' storage class

reply Funog <funog ifrance.com> writes:
'in' is equivalent to final const scope.
I can't understand the point of making the variable 'final' if it's already
'const' ?
Sep 05 2007
parent reply Nathan Reed <nathaniel.reed gmail.com> writes:
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
Sep 05 2007
parent reply Funog <funog ifrance.com> writes:
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' ?
Sep 05 2007
parent reply Nathan Reed <nathaniel.reed gmail.com> writes:
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
Sep 05 2007
parent reply Funog <funog ifrance.com> writes:
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' ?
Sep 05 2007
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
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.
Sep 05 2007
parent reply Funog <funog ifrance.com> writes:
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
Sep 06 2007
next sibling parent Jason House <jason.james.house gmail.com> writes:
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' ?

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' ?

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...
Sep 06 2007
prev sibling parent torhu <no spam.invalid> writes:
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.
Sep 08 2007