digitalmars.D - PROPOSAL: structs be passed by reference...
- Regan Heath (15/15) May 27 2004 I thought I'd make this it's own little thread..
- J Anderson (5/19) May 28 2004 If your worried about efficiency, the compiler will optimise the code
- imr1984 (5/29) May 28 2004 I disagree JA. As I said in the other thread on this topic, if you have ...
- J Anderson (5/44) May 28 2004 When the function is exported it can be labelled with what type of
- Juanjo =?ISO-8859-15?Q?=C1lvarez?= (2/7) May 28 2004
- davepermen (7/40) May 28 2004 only c is that dump that it doesn't export the way you have to pass
- Kevin Bealer (9/11) May 30 2004 C has a well documented policy: all arguments are always "in". If the p...
- davepermen (10/22) Jun 03 2004 but the caller doesn't KNOW what to pass in, and get back, actually.. (i...
- Regan Heath (15/36) May 31 2004 I was worried about efficiency, but also ... so you're saying D will pas...
- J Anderson (13/51) Jun 07 2004 The effect shouldn't be visible. If you modify the in struct, then the
- Regan Heath (17/75) Jun 07 2004 Yes. Otherwise you get side effects.
- J Anderson (23/43) Jun 07 2004 But the compiler can detect when its const and do it for you
- Regan Heath (18/66) Jun 07 2004 Do what? throw a compile time error because you have just tried to modif...
- Norbert Nemec (8/12) Jun 07 2004 This is true in many contexts but not referring to calling conventions: ...
- J Anderson (12/31) Jun 08 2004 An in-like operator makes a copy and allows you to work on the copy. A
- Norbert Nemec (27/33) Jun 07 2004 It definitely is faster if the data is needed only for the call:
- Andy Friesen (6/23) May 28 2004 In the case of extern(D), I agree. In the case of very small structs,
I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 27 2004
Regan Heath wrote:I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout. -- -Anderson: http://badmama.com.au/~anderson/
May 28 2004
In article <c96se7$ifr$2 digitaldaemon.com>, J Anderson says...Regan Heath wrote:I disagree JA. As I said in the other thread on this topic, if you have an exported function that takes a struct param, how can the caller of that function know wether it takes a ref or value, unless its in the prototype? D really needs to nail this one, and I wish Walter would comment on it.I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout. -- -Anderson: http://badmama.com.au/~anderson/
May 28 2004
imr1984 wrote:In article <c96se7$ifr$2 digitaldaemon.com>, J Anderson says...When the function is exported it can be labelled with what type of struct it requires. Of course if its a C function then you have no choice. -- -Anderson: http://badmama.com.au/~anderson/Regan Heath wrote:I disagree JA. As I said in the other thread on this topic, if you have an exported function that takes a struct param, how can the caller of that function know wether it takes a ref or value, unless its in the prototype? D really needs to nail this one, and I wish Walter would comment on it.I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout. -- -Anderson: http://badmama.com.au/~anderson/
May 28 2004
What about a simple, intuitive a logical "refin" keyword? imr1984 wrote:In article <c96se7$ifr$2 digitaldaemon.com>, J Anderson says...I disagree JA. As I said in the other thread on this topic, if you have an exported function that takes a struct param, how can the caller of that function know wether it takes a ref or value, unless its in the prototype? D really needs to nail this one, and I wish Walter would comment on it.
May 28 2004
only c is that dump that it doesn't export the way you have to pass parameters, and what parameters... even c++ does export the whole info.. "imr1984" <imr1984_member pathlink.com> schrieb im Newsbeitrag news:c97691$10vd$1 digitaldaemon.com...In article <c96se7$ifr$2 digitaldaemon.com>, J Anderson says...inout.Regan Heath wrote:I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in asfunction-- -Anderson: http://badmama.com.au/~anderson/I disagree JA. As I said in the other thread on this topic, if you have an exported function that takes a struct param, how can the caller of thatknow wether it takes a ref or value, unless its in the prototype? D reallyneedsto nail this one, and I wish Walter would comment on it.
May 28 2004
In article <c9801q$27d1$1 digitaldaemon.com>, davepermen says...only c is that dump that it doesn't export the way you have to pass parameters, and what parameters... even c++ does export the whole info..C has a well documented policy: all arguments are always "in". If the parameter is a pointer, you can modify what it points to, but the argument, the pointer itself, is copied. Another example of the C language philosophy: the programmer understands what the code does but the language just copies bytes. C provides just enough abstraction to hide differences in assembler languages. Whether you passing the data in or out or just preventing optimization of that variable, is not the language's concern (in C). Kevin
May 30 2004
but the caller doesn't KNOW what to pass in, and get back, actually.. (in linking stage) "Kevin Bealer" <Kevin_member pathlink.com> schrieb im Newsbeitrag news:c9c2qf$1vl6$1 digitaldaemon.com...In article <c9801q$27d1$1 digitaldaemon.com>, davepermen says...parameteronly c is that dump that it doesn't export the way you have to pass parameters, and what parameters... even c++ does export the whole info..C has a well documented policy: all arguments are always "in". If theis a pointer, you can modify what it points to, but the argument, thepointeritself, is copied. Another example of the C language philosophy: theprogrammerunderstands what the code does but the language just copies bytes. Cprovidesjust enough abstraction to hide differences in assembler languages.Whether youpassing the data in or out or just preventing optimization of thatvariable, isnot the language's concern (in C). Kevin
Jun 03 2004
On Fri, 28 May 2004 16:15:06 +0800, J Anderson <REMOVEanderson badmama.com.au> wrote:Regan Heath wrote:I was worried about efficiency, but also ... so you're saying D will pass my large structs by reference, not value? Ok, next question. If I pass a struct (it gets passed as an 'in' parameter by default) can the function modify it, what happens if it does? From what you say above it can have 2 different effects depending on whether the compiler optimized it or not. I think this is bad. I think 'in' should mean pass by reference AND cannot be modified. The latter causing a compile time error. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout.
May 31 2004
Regan Heath wrote:On Fri, 28 May 2004 16:15:06 +0800, J Anderson <REMOVEanderson badmama.com.au> wrote:The effect shouldn't be visible. If you modify the in struct, then the compiler *must* make a copy of it. However if you don't modify it then the compiler has the choice at compile time. I think about it like this, if the compiler can get away with it without making a side effect then it will. As I said before pass by reference is often very inefficient. If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do. BTW: I don't know how smart the dmd compiler is, at the moment Walter may have used the simplest method and just make a byte copy although he has said that the above does work. -- -Anderson: http://badmama.com.au/~anderson/Regan Heath wrote:I was worried about efficiency, but also ... so you're saying D will pass my large structs by reference, not value? Ok, next question. If I pass a struct (it gets passed as an 'in' parameter by default) can the function modify it, what happens if it does? From what you say above it can have 2 different effects depending on whether the compiler optimized it or not. I think this is bad. I think 'in' should mean pass by reference AND cannot be modified. The latter causing a compile time error. Regan.I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout.
Jun 07 2004
On Tue, 08 Jun 2004 09:36:04 +0800, J Anderson <REMOVEanderson badmama.com.au> wrote:Regan Heath wrote:Yes. Otherwise you get side effects.On Fri, 28 May 2004 16:15:06 +0800, J Anderson <REMOVEanderson badmama.com.au> wrote:The effect shouldn't be visible. If you modify the in struct, then the compiler *must* make a copy of it.Regan Heath wrote:I was worried about efficiency, but also ... so you're saying D will pass my large structs by reference, not value? Ok, next question. If I pass a struct (it gets passed as an 'in' parameter by default) can the function modify it, what happens if it does? From what you say above it can have 2 different effects depending on whether the compiler optimized it or not. I think this is bad. I think 'in' should mean pass by reference AND cannot be modified. The latter causing a compile time error. Regan.I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.If your worried about efficiency, the compiler will optimise the code for the best case. If you want to change the struct, pass it in as inout.However if you don't modify it then the compiler has the choice at compile time. I think about it like this, if the compiler can get away with it without making a side effect then it will.This idea, and my other to change 'in' to imply "const like" behaviour are linked. I don't think you should be allowed to modify an 'in' parameter without making a copy, after all if you want to modify it, it's either: - an inout incorrectly labelled as an in - only going to be modified for the duration of the function, so why not an explicit copy as shown above. So given the above, it makes no sense for the compiler to give you a copy of a struct, for you to copy it again.As I said before pass by reference is often very inefficient.When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.Assuming pass-by-reference can be inefficient, I agree.BTW: I don't know how smart the dmd compiler is, at the moment Walter may have used the simplest method and just make a byte copy although he has said that the above does work.-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 07 2004
Regan Heath wrote:Yes. Otherwise you get side effects.But the compiler can detect when its const and do it for you automaticly. I think there is a place for const but not here.However if you don't modify it then the compiler has the choice at compile time. I think about it like this, if the compiler can get away with it without making a side effect then it will.This idea, and my other to change 'in' to imply "const like" behaviour are linked. I don't think you should be allowed to modify an 'in' parameter without making a copy, after all if you want to modify it, it's either: - an inout incorrectly labelled as an in - only going to be modified for the duration of the function, so why not an explicit copy as shown above.So given the above, it makes no sense for the compiler to give you a copy of a struct, for you to copy it again.If you explicitly copy it then you are giving the compiler even more work (although the optimiser may be able to remove some of it). That is you now have a reference copy and an array copy.What is often forgotten with references is that an extra memory location is required and things can't be kept in cache so well. I'm not saying that copying a large struct is a good thing but copying a small structs (32 - 128 bits) can be. It's best to test these theories out (as I have done previously in C++) out. When you assign a reference you have to access the variable though the reference, rather then directly accessing it from the stack (which is on many cpus is automaticly cashed). Quit often what happens is not what you think. Keeping things in cache is a major field of optimisation these days considering its many times faster then ram. You don't want your program sitting around wasting cycles, waiting for some memory to be placed in cache. Best let the compiler make the best choice about how to handle your code for these types of details.As I said before pass by reference is often very inefficient.When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?I think const should go in somewhere but there still should be an in like operator somewhere. -- -Anderson: http://badmama.com.au/~anderson/If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.Assuming pass-by-reference can be inefficient, I agree.
Jun 07 2004
On Tue, 08 Jun 2004 12:33:11 +0800, J Anderson <REMOVEanderson badmama.com.au> wrote:Do what? throw a compile time error because you have just tried to modify it? that is what I want.Yes. Otherwise you get side effects.But the compiler can detect when its const and do it for you automaticly.However if you don't modify it then the compiler has the choice at compile time. I think about it like this, if the compiler can get away with it without making a side effect then it will.This idea, and my other to change 'in' to imply "const like" behaviour are linked. I don't think you should be allowed to modify an 'in' parameter without making a copy, after all if you want to modify it, it's either: - an inout incorrectly labelled as an in - only going to be modified for the duration of the function, so why not an explicit copy as shown above.I think there is a place for const but not here.Why not, it seems the perfect place to me. The function designer knows what access they require to the input. That access should never change (if it did the fn would not be the same fn and would cause user code to behave strangely).Good points.So given the above, it makes no sense for the compiler to give you a copy of a struct, for you to copy it again.If you explicitly copy it then you are giving the compiler even more work (although the optimiser may be able to remove some of it). That is you now have a reference copy and an array copy.What is often forgotten with references is that an extra memory location is required and things can't be kept in cache so well. I'm not saying that copying a large struct is a good thing but copying a small structs (32 - 128 bits) can be. It's best to test these theories out (as I have done previously in C++) out. When you assign a reference you have to access the variable though the reference, rather then directly accessing it from the stack (which is on many cpus is automaticly cashed). Quit often what happens is not what you think.As I said before pass by reference is often very inefficient.When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?Keeping things in cache is a major field of optimisation these days considering its many times faster then ram. You don't want your program sitting around wasting cycles, waiting for some memory to be placed in cache. Best let the compiler make the best choice about how to handle your code for these types of details.I'm not saying I don't want the compiler to manage all that jazz. What I am saying is that I think 'in' should imply const'ness and that I want the most efficient struct passing possible (which I *thought* was by reference - thank you for explaining)The current 'in' doesn't do anything, why not change it to do something, like enforce constness. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/I think const should go in somewhere but there still should be an in like operator somewhere.If you restrict the compiler to pass-by-reference then your limiting what optimisations the compiler can do.Assuming pass-by-reference can be inefficient, I agree.
Jun 07 2004
J Anderson wrote:Best let the compiler make the best choice about how to handle your code for these types of details.This is true in many contexts but not referring to calling conventions: The efficiency does not only depend on the internals of the routine but also on its use. If the compiler does inlining, it can do all the optimizations needed. Otherwise, there is no way to deduct which calling convention would be most efficient in general.I think const should go in somewhere but there still should be an in like operator somewhere.What would you consider the difference between a "const" and an "in-like" operator?
Jun 07 2004
Norbert Nemec wrote:J Anderson wrote:An in-like operator makes a copy and allows you to work on the copy. A const like operator does not allow you to work on the copy (if indeed it is a copy). I think this has been suggested before.... default - const in in - like in now out - like out now inout - like inout now That way you wouldn't have all those consts keywords floating around like Walter hates. It wouldn't be to hard to convert existing programs. -- -Anderson: http://badmama.com.au/~anderson/Best let the compiler make the best choice about how to handle your code for these types of details.This is true in many contexts but not referring to calling conventions: The efficiency does not only depend on the internals of the routine but also on its use. If the compiler does inlining, it can do all the optimizations needed. Otherwise, there is no way to deduct which calling convention would be most efficient in general.I think const should go in somewhere but there still should be an in like operator somewhere.What would you consider the difference between a "const" and an "in-like" operator?
Jun 08 2004
Regan Heath wrote:On Tue, 08 Jun 2004 09:36:04 +0800, J AndersonIt definitely is faster if the data is needed only for the call: ------------ struct A { ... } A produce() { ... } void consume(A value) { ... } consume(produce()); ------------ Unfortunately, this is something the compiler cannot decide by looking only at the routine, but it depends on the usage. Therefore, it should be left to the programmer to specify whether a struct should be passed by value or by reference. My suggestion would be the aforementioned idea: use "in" to indicate pass-by-reference and no modifier to indicate pass-by-value. In the first case, we should forbid writing to the argument alltogether (effectively turning "in" into C++-style "const &"). Making a copy of a pass-by-reference argument never is as efficient as doing pass-by-value in the first place. If the programmer has to do the copying explicitely, it will be more obvious that there is some extra cost. Of course, all of this does not matter if the compiler inlines the function, so it might be just as good to tell the programmer: if you care about performance, enable inlining...As I said before pass by reference is often very inefficient.When? using a very small struct? or something... even then doesn't it have to grab some memory, and copy the contents across? how is that faster than simply pushing an address?
Jun 07 2004
Regan Heath wrote:I thought I'd make this it's own little thread.. I think that structs should be passed by reference, not value, if you want to copy-in a struct you can by simply saying... struct foo { int a; int b; int c; } int foobar(foo _a) { foo a = _a; } I work as a C programmer, so I don't use classes etc, only structs, and I pretty much *always* pass a pointer to a struct not a struct itself.In the case of extern(D), I agree. In the case of very small structs, the compiler is presumably smart enough to be able to automatically create a copy on the stack, thereby mitigating any speed loss due to an extra dereference. -- andy
May 28 2004