www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using "in/out/ref"

reply David Ferenczi <raggae ferenczi.net> writes:
I would like to better understand the rationale of in/out/ref keywords, and
how they should be used.

If I don't use them, the function gets a mutable copy of the variable. So
the original variable won't change. At least in case of integral types.
(C-like convention?) In case of objects (object references?), or pointers
the function gets a mutable reference or a mutable pointer. This means that
the function can change the object, which is referred by the pointer or
reference. Is it right? Does this also mean that in case of objects or
pointes ref is the default?

In case of object references I would always use one of the in/out/ref
keywords to be explicit. (It could be also enforced by the compiler to be
explicit on references.)

Please correct me, if I'm wrong.

Regards,
David
Jun 18 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
David Ferenczi wrote:
 I would like to better understand the rationale of in/out/ref keywords, and
 how they should be used.
 
 If I don't use them, the function gets a mutable copy of the variable. So
 the original variable won't change. At least in case of integral types.
 (C-like convention?) In case of objects (object references?), or pointers
 the function gets a mutable reference or a mutable pointer. This means that
 the function can change the object, which is referred by the pointer or
 reference. Is it right? Does this also mean that in case of objects or
 pointes ref is the default?
 
 In case of object references I would always use one of the in/out/ref
 keywords to be explicit. (It could be also enforced by the compiler to be
 explicit on references.)
 
 Please correct me, if I'm wrong.
 
 Regards,
 David

In the case of objects, "ref" would be "pointer to pointer". So for example: class C { string s; this(string s) { this.s = s; } } void foo(C c) { c.s = "foo1"; c = new C("foo2"); // Compiles, but doesn't do anything // c is only changed for scope of function } void bar(in C c) { c.s = "bar1"; // Compile-time error! c = new C("bar2"); // Compile-time error! } void baz(ref C c) { c.s = "baz1"; c = new C("baz2"); } void main() { C c = new C("main"); foo(c); writefln(c.s); // Writes "foo1" baz(c); writefln(c.s); // Writes "baz2" }
Jun 18 2008
parent David Ferenczi <raggae ferenczi.net> writes:
Robert Fraser wrote:

 David Ferenczi wrote:
 I would like to better understand the rationale of in/out/ref keywords,
 and how they should be used.
 
 If I don't use them, the function gets a mutable copy of the variable. So
 the original variable won't change. At least in case of integral types.
 (C-like convention?) In case of objects (object references?), or pointers
 the function gets a mutable reference or a mutable pointer. This means
 that the function can change the object, which is referred by the pointer
 or reference. Is it right? Does this also mean that in case of objects or
 pointes ref is the default?
 
 In case of object references I would always use one of the in/out/ref
 keywords to be explicit. (It could be also enforced by the compiler to be
 explicit on references.)
 
 Please correct me, if I'm wrong.
 
 Regards,
 David

In the case of objects, "ref" would be "pointer to pointer". So for example: class C { string s; this(string s) { this.s = s; } } void foo(C c) { c.s = "foo1"; c = new C("foo2"); // Compiles, but doesn't do anything // c is only changed for scope of function } void bar(in C c) { c.s = "bar1"; // Compile-time error! c = new C("bar2"); // Compile-time error! } void baz(ref C c) { c.s = "baz1"; c = new C("baz2"); } void main() { C c = new C("main"); foo(c); writefln(c.s); // Writes "foo1" baz(c); writefln(c.s); // Writes "baz2" }

Thank you very much! Now I understand. :-)
Jun 18 2008