Passing arguments into functions - in, out, inout, const, and contracts

Kirk McDonald kirklin.mcdonald at
Sat Feb 10 22:24:58 PST 2007

Jason House wrote:
> I believe that everything (except maybe fundamental types such as int) 
> are passed by reference.  I'd expect "in" parameters to be considered 
> const, but I know that member functions can't be declared const.

No. This is precisely backwards. Everything is passed by value, except 
for certain high-level types like classes and arrays. Even then, 
in/out/inout still controls whether the function can reassign the reference.

> It seems to me that in/out/inout has no effect on how the language 
> operates.  I'm wondering how those affect the language.  Does "in" 
> impose a contract that the ending value must equal the starting value? I 
> also haven't thought of any good way to differentiate out from inout 
> from the compiler's standpoint (obviously, it makes sense to users).

Take the following code:

import std.stdio : writefln;

class Foo {
     int i;
     this(int i) { this.i = i; }

void func1(Foo f) {
     f = new Foo(100);
void func2(Foo f) {
     f.i = 30;
void func3(inout Foo f) {
     f = new Foo(200);
void func4(int i) {
     i = 20;
void func5(inout int i) {
     i = 25;

void main() {
     int i, j;
     Foo a, b, c;
     a = new Foo(1);
     b = new Foo(2);
     c = new Foo(3);

     writefln(a.i); // Prints 1. The reference was passed 'in', so the
                    // function does not change it.
     writefln(b.i); // Prints 30. The object was passed by reference,
                    // and the function mutated it.
     writefln(c.i); // Prints 200. The reference was passed 'inout',
                    // so the function does change it.
     writefln(i); // Prints 0. The int was passed 'in'.
     writefln(j); // Prints 25. The int was passed 'inout'.

Kirk McDonald
Pyd: Connecting D and Python

More information about the Digitalmars-d-learn mailing list