what's the difference between ref and inout in D2?

bearophile bearophileHUGS at lycos.com
Fri Mar 12 15:52:41 PST 2010


Trass3r:

>And that's good behavior imho.<

Here I prefer the C#/Java compilers, that don't initialize and turn the usage of initialized variables into an error.


>(at function entrance I guess).<

Yes. But you have seen in my program2 the variable x is initialized to 10 in the main program. This is a bit bug-prone because such value gets unused. It's like a value written before it's overwritten by its first init value. I think this only happens for 'out' arguments.


>I still don't get what you mean. Have an example?<

It's simple. This is a program that you can write now:

// program3
import std.stdio: writeln;

void spam(out int x, out int y) {
    x = 10;
    y = 20;
}

void main() {
    int x = 1;
    int y = 2;
    spam(x, y);
    writeln(x, " ", y); // prints 10 20
}


Once return values can be tuples too, you can write something like (invented syntax, it's not the best possible syntax):

// program4
import std.stdio: writeln;

(int, int) spam() {
    return (10, 20);
}

void main() {
    (int x, int y) = spam(x, y);
    writeln(x);
}


Here there is no risk of preassigning the values 1 and 2 that get lost, there is no risk of forgetting to add a 'out' attribute, etc. It's less bug-prone (but the programmer has to take care of using the correct order in the tuple, because they are not named. Fields in a Phobos2 Tuple can be named).


Using a Record/record of my dlibs1 (similar to Tuple of Phobos2) that's essentially a smarter struct today you can write something like this in D1 too:

// program5
import std.stdio: writeln;

Record!(int, int) spam() {
    return record(10, 20)
}
void main() {
    int x, y;
    derecord(spam(x, y), x, y);
    writeln(x);
}


Or in D2:

// program6
import std.stdio: writeln;

auto spam() {
    return record(10, 20);
}
void main() {
    int x, y;
    derecord(spam(x, y), x, y);
    writeln(x);
}

In D2 you may even be able to write:


// program7
import std.stdio: writeln;

auto spam() {
    return record(10, 20);
}
void main() {
    int x, y;
    derecord(x, y) = spam(x, y);
    writeln(x);
}


But it's not good.


And something like this is not nice looking at all:

// program8
import std.stdio: writeln;

auto spam() {
    return record(10, 20);
}
void main() {
    mixin(Derecord!("x", int, "y", int, spam(x, y)));
}

Bye,
bearophile7


More information about the Digitalmars-d-learn mailing list