digitalmars.D.learn - still confused about call by reference
- Hoenir (11/11) Oct 28 2007 I'm still a bit confused about call by reference. When do I have to
- Derek Parnell (50/63) Oct 28 2007 I'm no C++ user so I'm guessing a bit with the C++ syntax, but I'd code
- Hoenir (13/19) Oct 30 2007 Thanks for your code. But is there a way to use code like the following:
- Hoenir (2/2) Oct 30 2007 Always wondered why it uses real. It's because I use the following typed...
- Nathan Reed (4/25) Oct 30 2007 I think the opCall needs to be declared static.
- Hoenir (2/4) Oct 30 2007 opCall is used here as a "constructor" for that struct. Thus declaring
- Nathan Reed (9/13) Oct 30 2007 Right, it's used as a constructor. That's the point: it has to be
- Jarrett Billingsley (10/14) Oct 30 2007 This is the stupid compromise that we got instead of struct ctors in D1....
- Saaa (3/3) Oct 30 2007 What does this mean exactly ?
- Bill Baxter (11/15) Oct 30 2007 You can say
- Jarrett Billingsley (24/39) Oct 30 2007 I was thinking more along the lines of
- Saaa (8/50) Oct 30 2007 Ah, I see what you mean.
- Hoenir (13/16) Oct 31 2007 Thanks a lot for that link!
- Jarrett Billingsley (8/14) Oct 31 2007 Struct literals were added after static opCall was 'blessed', so static
- Jarrett Billingsley (4/18) Oct 31 2007 Oh and I guess I should mention, struct to struct assignment is always
- Hoenir (4/11) Oct 31 2007 Yeah, this makes sense. I will use literals nevertheless cause I can't
- Nathan Reed (20/33) Oct 28 2007 In C++, const references are used to signal the data is not changed by
- Hoenir (3/41) Oct 29 2007 I think I read somewhere, objects are automatically passed by reference
- Nathan Reed (8/10) Oct 29 2007 Object types in D are indeed reference types, so passing these by
- Hoenir (3/5) Oct 31 2007 http://www.digitalmars.com/d/1.0/struct.html tells the following:
- Nathan Reed (3/8) Oct 31 2007 That gets you a pointer. You don't need & to pass a value type to a
- Hoenir (3/5) Oct 31 2007 No I meant the argument passing:
- Bill Baxter (8/15) Oct 31 2007 In D that's written:
- Hoenir (6/17) Nov 01 2007 Ok, but ref is an alias for inout atm. And I think "in" is implicitly
- Jarrett Billingsley (7/23) Nov 01 2007 Your question was answered in the very first reply to your OP, by Derek:
- Bill Baxter (6/25) Nov 02 2007 Sorry, I'm using D1.x. What you ask is not possible with D1.x.
- Jarrett Billingsley (5/8) Oct 29 2007 'ref' is an alias of 'inout' at least for the time being. It was introd...
- Bill Baxter (3/12) Oct 29 2007 Also 'const inout' as a parameter doesn't make much sense either.
I'm still a bit confused about call by reference. When do I have to explicitly use the & operator and when to use in, out and inout? I want to convert my C++ vector struct to D: struct vec3 { vec3 operator+(const vec3& v) const {return vec3(x+v.x, y+v.y, z+v.z);} vec3 operator-(const vec3& v) const {return vec3(x-v.x, y-v.y, z-v.z);} I'm also wondering about how to handle the constness. Thanks in advance for any help :)
Oct 28 2007
On Mon, 29 Oct 2007 04:32:44 +0100, Hoenir wrote:I'm still a bit confused about call by reference. When do I have to explicitly use the & operator and when to use in, out and inout? I want to convert my C++ vector struct to D: struct vec3 { vec3 operator+(const vec3& v) const {return vec3(x+v.x, y+v.y, z+v.z);} vec3 operator-(const vec3& v) const {return vec3(x-v.x, y-v.y, z-v.z);} I'm also wondering about how to handle the constness. Thanks in advance for any help :)I'm no C++ user so I'm guessing a bit with the C++ syntax, but I'd code something like ... module vecs; struct vec3(VT) { private VT x,y,z; vec3 opAdd(const ref vec3 v) { vec3 t; t.x = x + v.x; t.y = y + v.y; t.z = z + v.z; return t; } vec3 opSub(const ref vec3 v) { vec3 t; t.x = x - v.x; t.y = y - v.y; t.z = z - v.z; return t; } void opCall(T,U,V)(const T a, const U b, const V c) { x = cast(VT)a; y = cast(VT)b; z = cast(VT)c; } private import std.string; string toString() { return std.string.format("[%s; %s; %s]", x,y,z); } } **** EXCEPT **** that 'const ref' crashes the compiler (see Bugzilla 1319) http://d.puremagic.com/issues/show_bug.cgi?id=1319 -- Derek (skype: derek.j.parnell) Melbourne, Australia 29/10/2007 2:58:45 PM
Oct 28 2007
Derek Parnell schrieb:void opCall(T,U,V)(const T a, const U b, const V c) { x = cast(VT)a; y = cast(VT)b; z = cast(VT)c; }Thanks for your code. But is there a way to use code like the following: vec3 opSub(vec3 v) {return vec3(x-v.x, y-v.y, z-v.z);} It doesn't work with vec3 opCall(U,V,W)(U a, V b, W c) { x = cast(T)a; y = cast(T)b; z = cast(T)c; return *this; } Tells me "type vec3!(real) is not an expression". (typedef double real) btw is it possible to return pointers?
Oct 30 2007
Always wondered why it uses real. It's because I use the following typedef: typedef vec3!(real) color;
Oct 30 2007
Hoenir wrote:Derek Parnell schrieb:I think the opCall needs to be declared static. Thanks, Nathan Reedvoid opCall(T,U,V)(const T a, const U b, const V c) { x = cast(VT)a; y = cast(VT)b; z = cast(VT)c; }Thanks for your code. But is there a way to use code like the following: vec3 opSub(vec3 v) {return vec3(x-v.x, y-v.y, z-v.z);} It doesn't work with vec3 opCall(U,V,W)(U a, V b, W c) { x = cast(T)a; y = cast(T)b; z = cast(T)c; return *this; } Tells me "type vec3!(real) is not an expression". (typedef double real) btw is it possible to return pointers?
Oct 30 2007
I think the opCall needs to be declared static.opCall is used here as a "constructor" for that struct. Thus declaring it static doesn't make any sense to me. Are you sure it must be static?
Oct 30 2007
Hoenir wrote:Right, it's used as a constructor. That's the point: it has to be callable without having an instance of the struct laying around - hence static. With a non-static opCall, you can use an instance of the struct as a callable entity. Static opCall lets you use the name of the struct itself as a callable entity. Thanks, Nathan ReedI think the opCall needs to be declared static.opCall is used here as a "constructor" for that struct. Thus declaring it static doesn't make any sense to me. Are you sure it must be static?
Oct 30 2007
"Hoenir" <mrmocool gmx.de> wrote in message news:fg7o1e$2lhs$1 digitalmars.com...This is the stupid compromise that we got instead of struct ctors in D1. Use a static opCall, Walter says, it'll get optimized out. That's great, but it makes it impossible to initialize an instance of a struct on the heap without factoring out the initialization to _another_ function, and it's just another stupid inconsistency which we'll have to live with even though D2 will have struct ctors. *sigh* You cacn read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.htmlI think the opCall needs to be declared static.opCall is used here as a "constructor" for that struct. Thus declaring it static doesn't make any sense to me. Are you sure it must be static?
Oct 30 2007
What does this mean exactly ? initialize an instance of a struct on the heap without factoring out the initialization to _another_ function
Oct 30 2007
Saaa wrote:What does this mean exactly ? initialize an instance of a struct on the heap without factoring out the initialization to _another_ functionYou can say MyStruct *x = new MyStruct; But even with a static opCall defined, this doesn't work MyStruct *x = new MyStruct(a,b,c); You have to do something like: MyStruct *x = new MyStruct; *x = MyStruct(a,b,c); Or that's what I guess he means, at least. I haven't actually tried the code above to see what it will do. --bb
Oct 30 2007
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fg8mpg$15gl$1 digitalmars.com...Saaa wrote:I was thinking more along the lines of struct S { int x, y; void init(int x, int y) { this.x = x; this.y = y; } static S opCall(int x, int y) { S s; s.init(x, y); return s; } } .. // Stack S s = S(3, 4); // Heap S* t = new S; t.init(5, 6);What does this mean exactly ? initialize an instance of a struct on the heap without factoring out the initialization to _another_ functionYou can say MyStruct *x = new MyStruct; But even with a static opCall defined, this doesn't work MyStruct *x = new MyStruct(a,b,c); You have to do something like: MyStruct *x = new MyStruct; *x = MyStruct(a,b,c); Or that's what I guess he means, at least. I haven't actually tried the code above to see what it will do. --bb
Oct 30 2007
Ah, I see what you mean. making your own _new would fix this, right? But yeah I think a constructor would be much better ;) I always put everything on the stack for speed purposes. I now that I think about it, I also never throw any struct array away. I try to allocate all necessary memory at the beginning of my programs. Ticks are allot more scarce than memory in my programs :D Anyway thanks.Saaa wrote:I was thinking more along the lines of struct S { int x, y; void init(int x, int y) { this.x = x; this.y = y; } static S opCall(int x, int y) { S s; s.init(x, y); return s; } } .. // Stack S s = S(3, 4); // Heap S* t = new S; t.init(5, 6);What does this mean exactly ? initialize an instance of a struct on the heap without factoring out the initialization to _another_ functionYou can say MyStruct *x = new MyStruct; But even with a static opCall defined, this doesn't work MyStruct *x = new MyStruct(a,b,c); You have to do something like: MyStruct *x = new MyStruct; *x = MyStruct(a,b,c); Or that's what I guess he means, at least. I haven't actually tried the code above to see what it will do. --bb
Oct 30 2007
You can read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.htmlThanks a lot for that link! Though I don't really get the purpose of opCall. For normal member initialization struct literals are completely sufficient. opCall would just make sense as a copy constructor, but this does not work. " static S opCall(S v) { S s; s.a = v.a + 1; return s; } } S s = 3; // sets s.a to 3 S t = s; // sets t.a to 3, S.opCall(s) is not called"
Oct 31 2007
"Hoenir" <mrmocool gmx.de> wrote in message news:fgb3h9$2q19$1 digitalmars.com...Struct literals were added after static opCall was 'blessed', so static opCall was the only way to fly for a while. Even then, the dynamic struct literals use a completely different syntax from the static struct initializers (another big *sigh*). But it's still useful to have a constructor function to i.e. check valid values, perform preprocessing on the values, fill in other members based on values that you give, etc.You can read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.htmlThanks a lot for that link! Though I don't really get the purpose of opCall. For normal member initialization struct literals are completely sufficient. opCall would just make sense as a copy constructor, but this does not work.
Oct 31 2007
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:fgb48g$2rqq$1 digitalmars.com..."Hoenir" <mrmocool gmx.de> wrote in message news:fgb3h9$2q19$1 digitalmars.com...Oh and I guess I should mention, struct to struct assignment is always defined as a bit copy. You can't intercept it in any way.Struct literals were added after static opCall was 'blessed', so static opCall was the only way to fly for a while. Even then, the dynamic struct literals use a completely different syntax from the static struct initializers (another big *sigh*). But it's still useful to have a constructor function to i.e. check valid values, perform preprocessing on the values, fill in other members based on values that you give, etc.You can read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.htmlThanks a lot for that link! Though I don't really get the purpose of opCall. For normal member initialization struct literals are completely sufficient. opCall would just make sense as a copy constructor, but this does not work.
Oct 31 2007
Yeah, this makes sense. I will use literals nevertheless cause I can't afford to check values etc. This vector class is supposed to be used in a ray tracing application.But it's still useful to have a constructor function to i.e. check valid values, perform preprocessing on the values, fill in other members based on values that you give, etc.Oh and I guess I should mention, struct to struct assignment is always defined as a bit copy. You can't intercept it in any way.Thanks for the info.
Oct 31 2007
Hoenir wrote:I'm still a bit confused about call by reference. When do I have to explicitly use the & operator and when to use in, out and inout? I want to convert my C++ vector struct to D: struct vec3 { vec3 operator+(const vec3& v) const {return vec3(x+v.x, y+v.y, z+v.z);} vec3 operator-(const vec3& v) const {return vec3(x-v.x, y-v.y, z-v.z);} I'm also wondering about how to handle the constness. Thanks in advance for any help :)In C++, const references are used to signal the data is not changed by the function, and is passed by reference purely for efficiency's sake. I believe the correct D equivalent is 'in'. The D spec states that 'in' is equivalent to 'final const scope', which means writing to the parameter is prevented, as in C++. The spec does not say whether 'in' results in pass-by-reference or not, but in this case, I believe that is a decision that should be made by the compiler, not the programmer. C++ non-const references are used to signal out-parameters, so the D equivalent would be out or inout, depending on whether your function wants to use the value that is passed in or not - 'out' parameters are initialized to their type's default value when the function begins, so any value that was there when the function was called gets clobbered, while 'inout' parameters let you read the original value. Honestly, I'm not entirely sure what D's 'ref' parameter-storage class is for, since AFAICT all the uses of pass-by-reference are covered by in, out, and inout. Thanks, Nathan Reed
Oct 28 2007
Nathan Reed schrieb:Hoenir wrote:I think I read somewhere, objects are automatically passed by reference and if you add in or out it means the pointer rather than the data.I'm still a bit confused about call by reference. When do I have to explicitly use the & operator and when to use in, out and inout? I want to convert my C++ vector struct to D: struct vec3 { vec3 operator+(const vec3& v) const {return vec3(x+v.x, y+v.y, z+v.z);} vec3 operator-(const vec3& v) const {return vec3(x-v.x, y-v.y, z-v.z);} I'm also wondering about how to handle the constness. Thanks in advance for any help :)In C++, const references are used to signal the data is not changed by the function, and is passed by reference purely for efficiency's sake. I believe the correct D equivalent is 'in'. The D spec states that 'in' is equivalent to 'final const scope', which means writing to the parameter is prevented, as in C++. The spec does not say whether 'in' results in pass-by-reference or not, but in this case, I believe that is a decision that should be made by the compiler, not the programmer. C++ non-const references are used to signal out-parameters, so the D equivalent would be out or inout, depending on whether your function wants to use the value that is passed in or not - 'out' parameters are initialized to their type's default value when the function begins, so any value that was there when the function was called gets clobbered, while 'inout' parameters let you read the original value. Honestly, I'm not entirely sure what D's 'ref' parameter-storage class is for, since AFAICT all the uses of pass-by-reference are covered by in, out, and inout. Thanks, Nathan Reed
Oct 29 2007
Hoenir wrote:I think I read somewhere, objects are automatically passed by reference and if you add in or out it means the pointer rather than the data.Object types in D are indeed reference types, so passing these by reference would mean you'd pass a reference to a reference. (This is useless for 'in' parameters, but allows the expected behavior for 'out' parameters.) Of course, references are implemented as pointers, but they're semantically distinct from pointers. Thanks, Nathan Reed
Oct 29 2007
Object types in D are indeed reference typeshttp://www.digitalmars.com/d/1.0/struct.html tells the following: "Whereas classes are reference types, structs are value types." so would I have to use the & operator?
Oct 31 2007
Hoenir wrote:That gets you a pointer. You don't need & to pass a value type to a 'ref' parameter.Object types in D are indeed reference typeshttp://www.digitalmars.com/d/1.0/struct.html tells the following: "Whereas classes are reference types, structs are value types." so would I have to use the & operator?
Oct 31 2007
That gets you a pointer. You don't need & to pass a value type to a 'ref' parameter.No I meant the argument passing: void foo(Struct& S) {...}
Oct 31 2007
Hoenir wrote:In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bbThat gets you a pointer. You don't need & to pass a value type to a 'ref' parameter.No I meant the argument passing: void foo(Struct& S) {...}
Oct 31 2007
In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bbOk, but ref is an alias for inout atm. And I think "in" is implicitly used if nothing other is specified, isn't it? So how would I pass a struct by reference but without being able to write (const & in C++)? and does this make sense(why is struct a value type)? Please excuse my noob questions. :-)
Nov 01 2007
"Hoenir" <mrmocool gmx.de> wrote in message news:fgcaem$2rju$1 digitalmars.com...Your question was answered in the very first reply to your OP, by Derek: void foo(const ref S s) { } And it was also mentioned that 'const ref' crashes the compiler.In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bbOk, but ref is an alias for inout atm. And I think "in" is implicitly used if nothing other is specified, isn't it? So how would I pass a struct by reference but without being able to write (const & in C++)? and does this make sense(why is struct a value type)? Please excuse my noob questions. :-)
Nov 01 2007
Hoenir wrote:Yes.In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bbOk, but ref is an alias for inout atm. And I think "in" is implicitly used if nothing other is specified, isn't it?So how would I pass a struct by reference but without being able to write (const & in C++)? and does this make sense(why is struct a value type)? Please excuse my noob questions. :-)Sorry, I'm using D1.x. What you ask is not possible with D1.x. I expect as others have said that "const ref" will do it in D2.x as soon as that stops crashing the compiler. --bb
Nov 02 2007
"Nathan Reed" <nathaniel.reed gmail.com> wrote in message news:fg40ac$2fuo$1 digitalmars.com...Honestly, I'm not entirely sure what D's 'ref' parameter-storage class is for, since AFAICT all the uses of pass-by-reference are covered by in, out, and inout.'ref' is an alias of 'inout' at least for the time being. It was introduced for forwards compatibility, as it seems likely that we will be getting reference returns, and returning an 'inout' doesn't really make much sense.
Oct 29 2007
Jarrett Billingsley wrote:"Nathan Reed" <nathaniel.reed gmail.com> wrote in message news:fg40ac$2fuo$1 digitalmars.com...Also 'const inout' as a parameter doesn't make much sense either. --bbHonestly, I'm not entirely sure what D's 'ref' parameter-storage class is for, since AFAICT all the uses of pass-by-reference are covered by in, out, and inout.'ref' is an alias of 'inout' at least for the time being. It was introduced for forwards compatibility, as it seems likely that we will be getting reference returns, and returning an 'inout' doesn't really make much sense.
Oct 29 2007