digitalmars.D.learn - still confused about call by reference
- Hoenir <mrmocool gmx.de> Oct 28 2007
- Derek Parnell <derek nomail.afraid.org> Oct 28 2007
- Hoenir <mrmocool gmx.de> Oct 30 2007
- Hoenir <mrmocool gmx.de> Oct 30 2007
- Nathan Reed <nathaniel.reed gmail.com> Oct 30 2007
- Hoenir <mrmocool gmx.de> Oct 30 2007
- Nathan Reed <nathaniel.reed gmail.com> Oct 30 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Oct 30 2007
- "Saaa" <empty needmail.com> Oct 30 2007
- Bill Baxter <dnewsgroup billbaxter.com> Oct 30 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Oct 30 2007
- "Saaa" <empty needmail.com> Oct 30 2007
- Hoenir <mrmocool gmx.de> Oct 31 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Oct 31 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Oct 31 2007
- Hoenir <mrmocool gmx.de> Oct 31 2007
- Nathan Reed <nathaniel.reed gmail.com> Oct 28 2007
- Hoenir <mrmocool gmx.de> Oct 29 2007
- Nathan Reed <nathaniel.reed gmail.com> Oct 29 2007
- Hoenir <mrmocool gmx.de> Oct 31 2007
- Nathan Reed <nathaniel.reed gmail.com> Oct 31 2007
- Hoenir <mrmocool gmx.de> Oct 31 2007
- Bill Baxter <dnewsgroup billbaxter.com> Oct 31 2007
- Hoenir <mrmocool gmx.de> Nov 01 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Nov 01 2007
- Bill Baxter <dnewsgroup billbaxter.com> Nov 02 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Oct 29 2007
- Bill Baxter <dnewsgroup billbaxter.com> Oct 29 2007
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; }
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: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; }
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?
I think the opCall needs to be declared static. Thanks, Nathan Reed
Oct 30 2007
I think the opCall needs to be declared static.
it static doesn't make any sense to me. Are you sure it must be static?
Oct 30 2007
Hoenir wrote:I think the opCall needs to be declared static.
it static doesn't make any sense to me. Are you sure it must be static?
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 Reed
Oct 30 2007
"Hoenir" <mrmocool gmx.de> wrote in message news:fg7o1e$2lhs$1 digitalmars.com...I think the opCall needs to be declared static.
static doesn't make any sense to me. Are you sure it must be static?
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.html
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_ function
You 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:What does this mean exactly ? initialize an instance of a struct on the heap without factoring out the initialization to _another_ function
You 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
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);
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_ function
You 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
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);
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.
Oct 30 2007
You can read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.html
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...You can read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.html
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.
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.
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...You can read all about it in "Dynamic Initializaion of Structs" here: http://www.digitalmars.com/d/1.0/struct.html
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.
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.
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.
Oct 31 2007
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.
afford to check values etc. This vector class is supposed to be used in a ray tracing application.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.
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'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
and if you add in or out it means the pointer rather than the data.
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 types
"Whereas classes are reference types, structs are value types." so would I have to use the & operator?
Oct 31 2007
Hoenir wrote:Object types in D are indeed reference types
"Whereas classes are reference types, structs are value types." so would I have to use the & operator?
That gets you a pointer. You don't need & to pass a value type to a 'ref' parameter.
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: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) {...}
In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bb
Oct 31 2007
In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bb
Ok, 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...In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bb
Ok, 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. :-)
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.
Nov 01 2007
Hoenir wrote:In D that's written: void foo(ref Struct S) {...} And called like: Struct s; foo(s); --bb
Ok, but ref is an alias for inout atm. And I think "in" is implicitly used if nothing other is specified, isn't it?
Yes.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...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.
Also 'const inout' as a parameter doesn't make much sense either. --bb
Oct 29 2007









Hoenir <mrmocool gmx.de> 