Thread overview
struct vs built-in type
Dec 17, 2014
Jack Applegame
Dec 17, 2014
Rikki Cattermole
Dec 17, 2014
Daniel Kozák
Dec 17, 2014
Jack Applegame
December 17, 2014
Code:

import std.stdio;

struct Bar {
	int payload;
	alias payload this;
}
struct Foo {
	private {
		Bar m_bar;
		int m_baz;
	}
	@property {
		Bar bar() { return m_bar; }
		void bar(Bar v) { m_bar = v; }
		int baz() { return m_baz; }
		void baz(int v) { m_baz = v; }
	}
}

void main() {
	Foo foo;
	foo.bar += 4; // Compiles. Why?
	foo.baz += 4; // Error: foo.baz() is not an lvalue
}

foo.baz() is not lvalue. It's true.
But foo.bar() is lvalue. Why? I expected the same error. This line has no effect, but the compiler does not issue even a warning.

DMD64 D Compiler v2.066.1. CentOS 7
December 17, 2014
On 17/12/2014 8:57 p.m., Jack Applegame wrote:
> Code:
>
> import std.stdio;
>
> struct Bar {
>      int payload;
>      alias payload this;
> }
> struct Foo {
>      private {
>          Bar m_bar;
>          int m_baz;
>      }
>      @property {
>          Bar bar() { return m_bar; }
>          void bar(Bar v) { m_bar = v; }
>          int baz() { return m_baz; }
>          void baz(int v) { m_baz = v; }
>      }
> }
>
> void main() {
>      Foo foo;
>      foo.bar += 4; // Compiles. Why?
>      foo.baz += 4; // Error: foo.baz() is not an lvalue
> }
>
> foo.baz() is not lvalue. It's true.
> But foo.bar() is lvalue. Why? I expected the same error. This line has
> no effect, but the compiler does not issue even a warning.
>
> DMD64 D Compiler v2.066.1. CentOS 7

In this case, Bar can be treated as a reference type.
Where as a primitive type such as int is not. It is a literal.

Although I swear remembering this was a compiler bug and there was a discussion about it.

But just for thought:
struct Foo {
	string text;	
}

void main() {
	Foo foo;
	foo.doit;	
	
	import std.stdio;
	writeln(foo.text);
}


Given definition of doit:
void doit(Foo foo) {
	foo.text = "hi";	
}

It'll output a new line and thats it.
But for this:
void doit(ref Foo foo) {
	foo.text = "hi";	
}

It'll output hi.
In this case its explicitly provided by reference not as a literal.
December 17, 2014
V Wed, 17 Dec 2014 07:57:24 +0000
Jack Applegame via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com> napsáno:

> Code:
> 
> import std.stdio;
> 
> struct Bar {
> 	int payload;
> 	alias payload this;
> }
> struct Foo {
> 	private {
> 		Bar m_bar;
> 		int m_baz;
> 	}
> 	@property {
> 		Bar bar() { return m_bar; }
> 		void bar(Bar v) { m_bar = v; }
> 		int baz() { return m_baz; }
> 		void baz(int v) { m_baz = v; }
> 	}
> }
> 
> void main() {
> 	Foo foo;
> 	foo.bar += 4; // Compiles. Why?
> 	foo.baz += 4; // Error: foo.baz() is not an lvalue
> }
> 
> foo.baz() is not lvalue. It's true.
> But foo.bar() is lvalue. Why? I expected the same error. This
> line has no effect, but the compiler does not issue even a
> warning.
> 
> DMD64 D Compiler v2.066.1. CentOS 7

This is definitely compiler bug (if you print bar value it is still zero). This should work only with ref by spec

module main;
import std.stdio;

struct Bar {
    int payload;
    alias payload this;
}
struct Foo {
    private {
        Bar m_bar;
        int m_baz;
    }
    @property {
        ref Bar bar() { return m_bar; }
        void bar(Bar v) { m_bar = v; }
        ref int baz() { return m_baz; }
        void baz(int v) { m_baz = v; }
    }
}

void main() {
    Foo foo;
    foo.bar += 4;
    foo.baz += 4;
    writeln(foo.bar);
}

December 17, 2014
On Wednesday, 17 December 2014 at 08:09:44 UTC, Daniel Kozák via Digitalmars-d-learn wrote:
> This should work only with ref by spec
I totally agree.