Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
August 20, 2009 Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
This post is about D2 compiler/language. Is the following code supposed to be wrong in D2? (and if so, then why?) import std.c.stdio: printf; struct S { int x, y; } S produce() { S s = S(10, 20); return s; } void show(ref S s) { printf("%d %d\n", s.x, s.y); } void main() { show(produce()); } That code works in D1.042, while DMD V.2.031 gives the errors: test.d(10): Error: function temp.show (ref S s) does not match parameter types (S) test.d(10): Error: produce() is not an lvalue After a gentle suggestion by Kirk McDonald I have also tried the following signatures, with similar error messages: void show(ref const(S) s) { void show(const ref S s) { passing locally-defined structs by ref is handy (the LDC compiler is currently able to do it, as older D1 compilers too). Bye, bearophile |
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Thu, 20 Aug 2009 18:15:07 -0400, bearophile wrote:
> This post is about D2 compiler/language. Is the following code supposed to be wrong in D2? (and if so, then why?)
>
> import std.c.stdio: printf;
>
> struct S { int x, y; }
>
> S produce() {
> S s = S(10, 20);
> return s;
> }
>
> void show(ref S s) {
> printf("%d %d\n", s.x, s.y);
> }
>
> void main() {
> show(produce());
> }
>
>
> That code works in D1.042, while DMD V.2.031 gives the errors:
> test.d(10): Error: function temp.show (ref S s) does not match parameter
> types (S) test.d(10): Error: produce() is not an lvalue
>
>
> After a gentle suggestion by Kirk McDonald I have also tried the
> following signatures, with similar error messages: void show(ref
> const(S) s) {
> void show(const ref S s) {
>
> passing locally-defined structs by ref is handy (the LDC compiler is currently able to do it, as older D1 compilers too).
>
> Bye,
> bearophile
Note that I don't know much about what I'm saying :)
This is probably related to an early conversation, not sure which one, but if I recall correctly this is supposed to be an error.
The problem is that produce() is returning a temporary variable which would have no affect if modified. The idea is that such modification is unintended and should be flag as an error.
If you are interested in performance than I'd think void show(const S s) should be reasonable, but that could have threading issues if the compiler makes it a reference.
|
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | By const ref seems reasonable to allow, but by ref is bug prone. Why is it handy? |
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lutger |
Lutger wrote:
> By const ref seems reasonable to allow, but by ref is bug prone. Why is it handy?
struct Vector4
{
float[4] xyzw;
Vector opAdd(ref Vector rhs);
}
Vector code can be made much faster using ref arguments, but if you use ref arguments, you can't have anything more complex than a single binary expression.
D's stance at the moment seems to be: "speed, convenience: pick one"
/sadface
|
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep:
>Vector code can be made much faster using ref arguments,<
You are right regarding DMD (that's what I was asking for), but LDC often is able to inline everything (if the method is short), so using ref leads to the same (high) performance.
Bye,
bearophile
|
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | On Fri, 21 Aug 2009 10:42:08 -0400, Daniel Keep <daniel.keep.lists@gmail.com> wrote:
>
>
> Lutger wrote:
>> By const ref seems reasonable to allow, but by ref is bug prone. Why is it
>> handy?
>
> struct Vector4
> {
> float[4] xyzw;
> Vector opAdd(ref Vector rhs);
> }
>
> Vector code can be made much faster using ref arguments, but if you use
> ref arguments, you can't have anything more complex than a single binary
> expression.
Hence why const ref is reasonable:
Vector opAdd(ref const Vector rhs) const;
The issue is possibly with ref. There are two reasons to use ref, 1 is to be able to change the data referenced, 2 is for passing speed.
1 is bad for rvalues. 2 should be ok for rvalues.
If there was a way to signify you only want to use ref for reason 2, there would be a good solution. Most of the time, that's const ref, but what you really want is head-const ref, which isn't currently possible. If a struct has references to other values, they might be lvalues, and you may want to be able to change them.
I'm uncertain as to how often you would want to pass an rvalue as a ref that had lvalue reference in it, but at the very least, ref const should be valid.
-Steve
|
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer |
Steven Schveighoffer wrote:
> ...
>
> The issue is possibly with ref. There are two reasons to use ref, 1 is to be able to change the data referenced, 2 is for passing speed.
>
> 1 is bad for rvalues. 2 should be ok for rvalues.
>
> If there was a way to signify you only want to use ref for reason 2, there would be a good solution. Most of the time, that's const ref, but what you really want is head-const ref, which isn't currently possible. If a struct has references to other values, they might be lvalues, and you may want to be able to change them.
>
> I'm uncertain as to how often you would want to pass an rvalue as a ref that had lvalue reference in it, but at the very least, ref const should be valid.
>
> -Steve
In my own code, I usually record my intent by using "inout" for variables I intend to modify and "ref" for ones which I don't.
Always seemed reasonable to me.
|
August 21, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep:
> In my own code, I usually record my intent by using "inout" for variables I intend to modify and "ref" for ones which I don't. Always seemed reasonable to me.
for the compiler they mean the same thing, but inout is being deprecated.
Bye,
bearophile
|
August 22, 2009 Re: Structs by ref in D2 | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile |
bearophile wrote:
> Daniel Keep:
>> In my own code, I usually record my intent by using "inout" for variables I intend to modify and "ref" for ones which I don't. Always seemed reasonable to me.
>
> for the compiler they mean the same thing, but inout is being deprecated.
>
> Bye,
> bearophile
I realise this. My point is that the two keywords pretty nicely sum up a difference in intent.
|
Copyright © 1999-2021 by the D Language Foundation