Detect the bug in the following code

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Wed Apr 15 11:05:19 PDT 2015


On 4/15/15 1:44 PM, Caspar wrote:
> On Wednesday, 15 April 2015 at 17:28:01 UTC, John Colvin wrote:
>> On Wednesday, 15 April 2015 at 14:44:48 UTC, Idan Arye wrote:
>>> import std.stdio;
>>>
>>> struct Foo {
>>>    bool registered = false;
>>>
>>>    void register(int x) {
>>>        writeln("Registering ", x);
>>>        register = true;
>>>    }
>>> }
>>>
>>> void main() {
>>>    Foo foo;
>>>    foo.register(10);
>>> }
>>
>> Property assignment syntax for non-property functions is a horrible,
>> horrible thing.
>
> Could someone please explain what is actually happening in that piece of
> code to a D newbie?
> I see what happens when I run the code but I don't get why it is happening.
> In particular what "register = true;" actually does in that case.

In D1, and in D2 (but we're trying to change it), assignment properties 
worked like this:

struct S
{
    void foo(int x);
}

S s;
s.foo = 1; // same as s.foo(1);

So what is happening is that:

register = true;

translates to:

register(true);

which then matches the call of register(int) because 'true' is treated as 1.

So while the caller really wanted to set the variable "registered" to 
true, he's recursively calling his own function.

Many of us think that this should not work, because we have a way to 
designate properties via:

@property void foo(int x);

So really only functions tagged with @property should be usable as 
setters. Getters, the distinction is less confusing, because the 
following aren't very different:

auto x = foo;
auto x = foo();

So the position myself and many of us here have is that normal functions 
can be used as getters, but only @property tagged functions should be 
usable as setters.

-Steve


More information about the Digitalmars-d mailing list