www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - several questions

reply "Saaa" <empty needmail.com> writes:
From the D1 documentation:
For dynamic array and object parameters, which are passed by reference, 
in/out/ref apply only to the reference and not the contents.

What exactly (internally memory wise) does 'passing' mean. Is it like 
copying?
And does this mean that static arrays are not passed by reference and should 
I use:
void func(ref array.ptr)
,because otherwise the whole array is passed (copied) ? (which sound slow:)

Another question :)

What is the advantage of making a function/variable static?
It makes it nonvirtual, right. Why is this good?
When should I make something static or final?

A private function/var can't used by anything in a 'lower' scope, right?

Well thats it for now =D 
Feb 15 2008
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Fri, 15 Feb 2008 20:53:21 +0100, Saaa <empty needmail.com> wrote:

 From the D1 documentation:
 For dynamic array and object parameters, which are passed by reference=

 in/out/ref apply only to the reference and not the contents.

 What exactly (internally memory wise) does 'passing' mean. Is it like
 copying?

It means that when used as a parameter to a function, a reference type = will just send (copy, if you will) a pointer to itself to the function, = = while a value type will copy all its data. 'Least I think that should be= = fairly correct.
 And does this mean that static arrays are not passed by reference and =

 should
 I use:
 void func(ref array.ptr)
 ,because otherwise the whole array is passed (copied) ? (which sound  =

 slow:)

I seriously doubt ut does. Not having checked, I won't say that with 100= % = certainty, though.
 Another question :)

 What is the advantage of making a function/variable static?
 It makes it nonvirtual, right. Why is this good?
 When should I make something static or final?

A static function or variable becomes a member of the class/struct = definition, instead of of the instance. Say you have class Foo { static int bar_static; // Shared by all instances of Foo, so if one of = = them changes the value, it's changed for all. int bar; // New int specific to each instance. Change this value, and = no = other instance will notice. static void doStuff(){} // Function with no 'this' pointer. Can be call= ed = using Foo.doStuff(), with no instance of Foo anywhere in your program. C= an = change only static members of Foo. void doStuff(){} // Function with 'this' pointer. Needs an instance on = = which to work. Can change static members of Foo, as well as normal membe= rs. }
 A private function/var can't used by anything in a 'lower' scope, righ=

Private in D means 'not accessible outside this module.' So this is = perfectly legal: class Foo { private int foo; } class Bar : Foo { void bar() { foo =3D 3; } } void doStuff() { Foo f =3D new Foo(); f.foo =3D 4; } You can however not change foo from inside a different source file = (module).
 Well thats it for now =3DD

Feb 15 2008
parent reply "Saaa" <empty needmail.com> writes:
Thanks!
Still bit uncertain about the static array though :)
But I think I understand static now, although I never use 'this' making it a 
bit more difficult to understand :)
If I say something like 'static int i=0;' within the main I can't use i for 
anything else in the whole program afterwards.
It makes variables into global variables :)
What exactly is 'having a this reference' ?
And what does final mean. (the attributes page doesn't say anything about it 
:/ )
Private is easy to understand, thanks.

 From the D1 documentation:
 For dynamic array and object parameters, which are passed by reference,
 in/out/ref apply only to the reference and not the contents.

 What exactly (internally memory wise) does 'passing' mean. Is it like
 copying?

It means that when used as a parameter to a function, a reference type will just send (copy, if you will) a pointer to itself to the function, while a value type will copy all its data. 'Least I think that should be fairly correct.
 And does this mean that static arrays are not passed by reference and 
 should
 I use:
 void func(ref array.ptr)
 ,because otherwise the whole array is passed (copied) ? (which sound 
 slow:)

I seriously doubt ut does. Not having checked, I won't say that with 100% certainty, though.
 Another question :)

 What is the advantage of making a function/variable static?
 It makes it nonvirtual, right. Why is this good?
 When should I make something static or final?

A static function or variable becomes a member of the class/struct definition, instead of of the instance. Say you have class Foo { static int bar_static; // Shared by all instances of Foo, so if one of them changes the value, it's changed for all. int bar; // New int specific to each instance. Change this value, and no other instance will notice. static void doStuff(){} // Function with no 'this' pointer. Can be called using Foo.doStuff(), with no instance of Foo anywhere in your program. Can change only static members of Foo. void doStuff(){} // Function with 'this' pointer. Needs an instance on which to work. Can change static members of Foo, as well as normal members. }
 A private function/var can't used by anything in a 'lower' scope, right?

Private in D means 'not accessible outside this module.' So this is perfectly legal: class Foo { private int foo; } class Bar : Foo { void bar() { foo = 3; } } void doStuff() { Foo f = new Foo(); f.foo = 4; } You can however not change foo from inside a different source file (module).
 Well thats it for now =D 

Feb 15 2008
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Fri, 15 Feb 2008 22:09:10 +0100, Saaa <empty needmail.com> wrote:

 Thanks!
 Still bit uncertain about the static array though :)
 But I think I understand static now, although I never use 'this' makin=

 it a
 bit more difficult to understand :)
 If I say something like 'static int i=3D0;' within the main I can't us=

 for
 anything else in the whole program afterwards.

A static variable inside a function (which I did not cover in my last = post), will keep its value after the function has exited, and even when = = it's being called again. This function: void sillyFunc() { static timesRun; timesRun++: writefln(timesRun); } will print the numer of times it's been run, for instance.
 It makes variables into global variables :)
 What exactly is 'having a this reference' ?

When you instantiate a struct or class, some piece of memory is allocate= d = for that instantiation. When you run a non-static member function, the = 'this' pointer points to this data, basically saying 'here I am, and my = = (again, non-static) member variables are offset from here.' Example: class Foo { int bar; void baz() { bar++; // equivalent of this.bar++ writefln(bar); = } } void main() { Foo f =3D new Foo(); // f now points to a memory location that will be = used f.baz(); // as 'this' pointer inside the function bar executed here. }
 And what does final mean. (the attributes page doesn't say anything  =

 about it

Final means 'this function cannot be overrided.' Subclasses of whatever = = class has a final function will not be able to implement their own = versions of the final function. class Foo { final void doStuff() { writefln("Foo.doStuff();"); } } class Bar : Foo { void doStuff() // here the compiler will complain "cannot override fin= al = function Foo.doStuff { writefln("Bar.doStuff();"); } }
 :/ )
 Private is easy to understand, thanks.

Feb 15 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Simen Kjaeraas:
 A static variable inside a function (which I did not cover in my last  
 post), will keep its value after the function has exited, and even when  
 it's being called again.

It's a global variable that can be accessed/used only inside the namespace of that function. Bye, bearophile
Feb 16 2008
parent reply "Saaa" <empty needmail.com> writes:
What exactly is the namespace of a function?

 A static variable inside a function (which I did not cover in my last
 post), will keep its value after the function has exited, and even when
 it's being called again.

It's a global variable that can be accessed/used only inside the namespace of that function. Bye, bearophile

Feb 16 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Saaa:

 What exactly is the namespace of a function?

Informally it's the set of names (variables, etc) that you can see and use from the code inside the function. (Probably it's a bit more complex than that, but the base is that one.) Bye, bearophile
Feb 16 2008
parent reply "Saaa" <empty needmail.com> writes:
Making it:
It's a global variable that can be accessed/used only inside, the set of 
names (variables, etc) that you can see and use from the code inside the 
function, aka namespace of that function.

Does it contradict with:
A static variable inside a function (which I did not cover in my last
post), will keep its value after the function has exited, and even when
it's being called again.

I can't tell :D

 What exactly is the namespace of a function?

Informally it's the set of names (variables, etc) that you can see and use from the code inside the function. (Probably it's a bit more complex than that, but the base is that one.) Bye, bearophile

Feb 17 2008
parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Sun, 17 Feb 2008 15:32:43 +0100, Saaa <empty needmail.com> wrote:

 Making it:
 It's a global variable that can be accessed/used only inside, the set of
 names (variables, etc) that you can see and use from the code inside the
 function, aka namespace of that function.

 Does it contradict with:
 A static variable inside a function (which I did not cover in my last
 post), will keep its value after the function has exited, and even when
 it's being called again.

 I can't tell :D

Both things are correct, only different wordings. I don't like calling static locals for global variables, for to me that implies them being available globally, which they are not. They do however share other features with global variables (namely retaining their value after the function has exited). Capiche?
Feb 17 2008
prev sibling parent reply "Saaa" <empty needmail.com> writes:
Thanks again,

I don't think I ever override a function, should I make them final then, for 
optimizing purposes, or is final only for classes?



 Thanks!
 Still bit uncertain about the static array though :)
 But I think I understand static now, although I never use 'this' making 
 it a
 bit more difficult to understand :)
 If I say something like 'static int i=0;' within the main I can't use i 
 for
 anything else in the whole program afterwards.

A static variable inside a function (which I did not cover in my last post), will keep its value after the function has exited, and even when it's being called again. This function: void sillyFunc() { static timesRun; timesRun++: writefln(timesRun); } will print the numer of times it's been run, for instance.
 It makes variables into global variables :)
 What exactly is 'having a this reference' ?

When you instantiate a struct or class, some piece of memory is allocated for that instantiation. When you run a non-static member function, the 'this' pointer points to this data, basically saying 'here I am, and my (again, non-static) member variables are offset from here.' Example: class Foo { int bar; void baz() { bar++; // equivalent of this.bar++ writefln(bar); } } void main() { Foo f = new Foo(); // f now points to a memory location that will be used f.baz(); // as 'this' pointer inside the function bar executed here. }
 And what does final mean. (the attributes page doesn't say anything  about 
 it

Final means 'this function cannot be overrided.' Subclasses of whatever class has a final function will not be able to implement their own versions of the final function. class Foo { final void doStuff() { writefln("Foo.doStuff();"); } } class Bar : Foo { void doStuff() // here the compiler will complain "cannot override final function Foo.doStuff { writefln("Bar.doStuff();"); } }
 :/ )
 Private is easy to understand, thanks.
 

Feb 16 2008
parent reply Christopher Wright <dhasenan gmail.com> writes:
Saaa wrote:
 Thanks again,
 
 I don't think I ever override a function, should I make them final then, for 
 optimizing purposes, or is final only for classes?

Are you developing an application or a library? If it's a library, don't final it unless it's deep in the bowels where nobody will reasonably tread, or unless the library really requires performance. If it's an application, feel free. You probably won't have much need for inheritance, but then, the optimizations from your final classes might not be that great. But really, it's your decision.
Feb 16 2008
parent reply "Saaa" <empty needmail.com> writes:
 Thanks again,

 I don't think I ever override a function, should I make them final then, 
 for optimizing purposes, or is final only for classes?

Are you developing an application or a library? If it's a library, don't final it unless it's deep in the bowels where nobody will reasonably tread, or unless the library really requires performance. If it's an application, feel free. You probably won't have much need for inheritance, but then, the optimizations from your final classes might not be that great.

This reads as making a function final will hurt the optimization. btw. I don't use classes :), only functions. (application)
 But really, it's your decision. 

Feb 17 2008
parent reply Christopher Wright <dhasenan gmail.com> writes:
Saaa wrote:
 Thanks again,

 I don't think I ever override a function, should I make them final then, 
 for optimizing purposes, or is final only for classes?

If it's a library, don't final it unless it's deep in the bowels where nobody will reasonably tread, or unless the library really requires performance. If it's an application, feel free. You probably won't have much need for inheritance, but then, the optimizations from your final classes might not be that great.

This reads as making a function final will hurt the optimization. btw. I don't use classes :), only functions. (application)

Marking a class or a method on a class as final can improve performance. DMD might not take advantage of that as often as you like. Marking a function that is not in a class as final should do absolutely nothing.
Feb 17 2008
parent "Saaa" <empty needmail.com> writes:
 Marking a class or a method on a class as final can improve performance. 
 DMD might not take advantage of that as often as you like.

 Marking a function that is not in a class as final should do absolutely 
 nothing.

Ah ok, thanks :)
Feb 17 2008
prev sibling next sibling parent downs <default_357-line yahoo.de> writes:
Saaa wrote:
 From the D1 documentation:
 For dynamic array and object parameters, which are passed by reference, 
 in/out/ref apply only to the reference and not the contents.
 
 What exactly (internally memory wise) does 'passing' mean. Is it like 
 copying?

int x = 4; // the value 4, assigned to x, is now outside of test. test(x); // here I pass the value 4, in the form of x, into test. int test ( int a ) { // 4, in the form of a, has been passed into test.
 And does this mean that static arrays are not passed by reference and should 
 I use:
 void func(ref array.ptr)
 ,because otherwise the whole array is passed (copied) ? (which sound slow:)
 

Complete misunderstanding. An array is basically this with syntax candy: struct array (T) { size_t length; T* ptr; } Now, that paragraph from the documentation basically means, that if you pass an array into a function, you really just pass its length and ptr. So all these keywords, ref, out, in .. apply to the ptr and length, not the array's contents. Basically, an array is a reference to the data, with additional length information. That's what's meant by "dynamic array [...] parameters [...] are passed by reference".
 Another question :)
 
 What is the advantage of making a function/variable static?
 It makes it nonvirtual, right. Why is this good?

 When should I make something static or final?
 

--downs
Feb 15 2008
prev sibling next sibling parent torhu <no spam.invalid> writes:
Saaa wrote:
 And does this mean that static arrays are not passed by reference and should 
 I use:
 void func(ref array.ptr)
 ,because otherwise the whole array is passed (copied) ? (which sound slow:)

Static arrays as passed as the address of the first element. So yes, that's 'by reference'. These two are implemented in the exact same way: void func(int[3] array); void func(int* ptr_to_some_ints); // used like: int[3] array = [1, 2, 3]; func(array); func(array.ptr); The important difference is that inside the second function, the compiler does not care about how many elements 'array' contains, and you don't get automatic array bounds checking.
Feb 15 2008
prev sibling next sibling parent reply "Saaa" <empty needmail.com> writes:
From what I understand now from all the replies, it would be better to 
change the sentence to:

For (dynamic) array and object parameters, which are passed by reference,
in/out/ref apply only to the reference and not the contents.


One last question:

How about passing a huge structure. Does this need something like a pointer 
to the struct?
I mean, is the passing done optimal here:

struct S{
int n1=1;
int n2=2;
..
int n999=999;
}

void func(S s){
..
}

void main (){
S t;
func(t);
..
} 
Feb 16 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Saaa <empty needmail.com> wrote:
 How about passing a huge structure. Does this need something like a pointer 
 to the struct?
 I mean, is the passing done optimal here:
 
 struct S{
 int n1=1;
 int n2=2;
 ..
 int n999=999;
 }
 
 void func(S s){
 ..
 }
 
 void main (){
 S t;
 func(t);
 ..
 } 

Use ref or pointer, whatever suits you best. Usually ref is preferable because it makes no difference at the call site: void func(ref S s){ .. } void main (){ S t; func(t); // only a pointer is actually passed .. } If you use a pointer though, you must explicitly pass an address of your struct: void func(S* s){ .. } void main (){ S t; func(&t); // explicit address expression .. } -- SnakE
Feb 16 2008
parent reply "Saaa" <empty needmail.com> writes:
But if I use a ref or a pointer, the function is allowed to change the 
variable.
Using 'in' will make a copy?
I thought ref was just a renaming of  'inout'.
But there is no way to only pass a reference without giving the function 
write permission?

I sent a lot of big arrays in structs, so I think this is kind of crucial 
for me :/

 Use ref or pointer, whatever suits you best.  Usually ref is preferable
 because it makes no difference at the call site:

 void func(ref S s){
 ..
 }

 void main (){
 S t;
 func(t);  // only a pointer is actually passed
 ..
 }

 If you use a pointer though, you must explicitly pass an address of your
 struct:

 void func(S* s){
 ..
 }

 void main (){
 S t;
 func(&t); // explicit address expression
 ..
 }

 -- 
 SnakE 

Feb 17 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Saaa wrote:
 But if I use a ref or a pointer, the function is allowed to change the 
 variable.
 Using 'in' will make a copy?

For D1, in is the same as nothing at all. In D2 I think in is the same as 'invariant'. So yeh, it will make a copy.
 I thought ref was just a renaming of  'inout'.
 But there is no way to only pass a reference without giving the function 
 write permission?
 
 I sent a lot of big arrays in structs, so I think this is kind of crucial 
 for me :/

No way in D1. Yes way in D2 (const ref or invariant ref should work in latest DMD). --bb
Feb 17 2008
parent "Saaa" <empty needmail.com> writes:
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
news:fp9ih7$29av$2 digitalmars.com...
 Saaa wrote:
 But if I use a ref or a pointer, the function is allowed to change the 
 variable.
 Using 'in' will make a copy?

For D1, in is the same as nothing at all. In D2 I think in is the same as 'invariant'. So yeh, it will make a copy.
 I thought ref was just a renaming of  'inout'.
 But there is no way to only pass a reference without giving the function 
 write permission?

 I sent a lot of big arrays in structs, so I think this is kind of crucial 
 for me :/

No way in D1. Yes way in D2 (const ref or invariant ref should work in latest DMD).

Thanks! This is really good to know. Now I understand why they changed inout to ref. This will greatly optimize my program as I use a LOT of big static arrays in structs. I'll use ref from now on for every passing of one of those :)
Feb 17 2008
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 15 Feb 2008 20:53:21 +0100, Saaa wrote:

 From the D1 documentation:
 For dynamic array and object parameters, which are passed by reference, 
 in/out/ref apply only to the reference and not the contents.
 
 What exactly (internally memory wise) does 'passing' mean. Is it like 
 copying?

When a function's parameter is either a dynamic (variable-length) array or an object, the function does not get a copy of the parameter's data given to it. Instead it gets the address of the array/object instance. Actually, for arrays the function gets both the address and the length. This is in contrast with structs, static (fixed-length) arrays, and basic data types. In these cases, the function does get a copy of the parameter's data.
 And does this mean that static arrays are not passed by reference and should 
 I use:
 void func(ref array.ptr)
 ,because otherwise the whole array is passed (copied) ? (which sound slow:)

Exactly (almost). Use this instead ... void func(ref X[n] array) Where 'X' is the array's datatype and 'n' is its fixed length. There is no need for the '.ptr' property when also using 'ref'. An alternative is to use pointers directly, but then you loose array-bounds checking. void func( X* array)
 Another question :)
 
 What is the advantage of making a function/variable static?
 It makes it nonvirtual, right. Why is this good?
 When should I make something static or final?

I assume by "function/variable" here, you are referring to a class member. You would make a function member 'static' if you wanted to call it without using a specific object. It belongs to the class and not a class instance (object). It is kind of like a free function that is scoped to the class's namespace. class Foo { static void Bar() { . . . } } . . . Foo.Bar(); // Call the Foo class's Bar function. You would make a variable member 'static' if you wanted to use it without requiring a specific object. It belongs to the class and not a class instance (object). It is kind of like a global variable that is scoped to the class's namespace. class Foo { static int nextid = 1; int myID; this() { synchronized {myId = nextid; nextid++;} } } . . . Foo A = new Foo; Foo B = new Foo; writefln("A=%s, B=%s, next=%s", A.myID, B.myID, Foo.nextid); // Displays "A=1, B=2, next=3"
 A private function/var can't used by anything in a 'lower' scope, right?

I'm not sure what you mean by 'lower' scope. A private function/variable can only be accessed from code within the same module as its declaration. However there is a bug, which has been around for years but Walter doesn't regard as urgent, where 'private' can be overturned if the reference to the private function/variable is fully qualifed. In that case, code from any module can access the "so called private" entity. // -- file AA.d --- private int c; // -- file BB.d --- c = 1; // correctly fails. AA.c = 2; // Incorrectly works. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Feb 16 2008
parent reply torhu <no spam.invalid> writes:
Derek Parnell wrote:
  > This is in contrast with structs, static (fixed-length) arrays, and 
basic
 data types. In these cases, the function does get a copy of the parameter's
 data.

No, static arrays are 'reference' types. Meaning they are passed as just the address of the first element. You have to wrap them in a struct to get copy semantics for them.
Feb 16 2008
parent Derek Parnell <derek psych.ward> writes:
On Sun, 17 Feb 2008 05:09:44 +0100, torhu wrote:

 Derek Parnell wrote:
   > This is in contrast with structs, static (fixed-length) arrays, and 
 basic
 data types. In these cases, the function does get a copy of the parameter's
 data.

No, static arrays are 'reference' types. Meaning they are passed as just the address of the first element. You have to wrap them in a struct to get copy semantics for them.

Thanks for the correction. I was sure that at one stage static arrays were passed by value. This will simplify some of my code now. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Feb 16 2008