September 10, 2012
On Monday, September 10, 2012 09:13:04 Jacob Carlborg wrote:
> On 2012-09-10 02:05, Namespace wrote:
> > I had never problems with that in C++.
> > If I have members which are const because they are assigned only one
> > time and needs no other assignment, why should I declare this member not
> > as const?
> > 
> > In the example I know exactly that I assign only one time a name to this struct, so why I should not declare it as const?
> 
> Perhaps declare "Name" as private and create a property getter for the field. I think this is a bit annoying as well, it worked in D1.

And it works just fine in D2. It's const that's the problem. In general, if you want a member variable to be "read-only" on a struct, I'd strongly advise using a getter property without a setter property rather than making it const, because const makes it so that stuff like the assignment operator doesn't work.

- Jonathan M Davis
September 10, 2012
On 2012-09-10 09:24, Jonathan M Davis wrote:

> And it works just fine in D2. It's const that's the problem. In general, if you
> want a member variable to be "read-only" on a struct, I'd strongly advise
> using a getter property without a setter property rather than making it const,
> because const makes it so that stuff like the assignment operator doesn't work.

Well, in D1 const was a nice shortcut for this.

-- 
/Jacob Carlborg
September 10, 2012
On Monday, September 10, 2012 09:30:59 Jacob Carlborg wrote:
> On 2012-09-10 09:24, Jonathan M Davis wrote:
> > And it works just fine in D2. It's const that's the problem. In general, if you want a member variable to be "read-only" on a struct, I'd strongly advise using a getter property without a setter property rather than making it const, because const makes it so that stuff like the assignment operator doesn't work.
> Well, in D1 const was a nice shortcut for this.

Whereas in D2, const is both something of fantastic wonder and utter despair. :)

- Jonathan M Davis
September 10, 2012
On Sunday, 9 September 2012 at 23:54:45 UTC, Jonathan M Davis
wrote:
>
> [SNIP]
>
> the default assignment operator illegal. You could overload it, and as long as
> it doesn't touch any of the const member variables, it would work, but the
> const member variable is stuck as it is, and anything trying to mutate is
> illegal.
>
> [SNIP]
>
> - Jonathan M Davis

Not to that it is my goal to be a pain, but the example I
provided *does* overload opAssign (and the CC), but it *doesn't*
work.

Notice the error message is:
"Error: tests[4] isn't mutable"
Which is simply not true.

The default assignment operator, when trying to do an assignment creates:
"Error: variable XXX cannot modify struct with immutable members."
But that is not what we are seeing.

It appears that when writting:
tests[4] = Test("Foobar");
It *looks* like compiler is eliding the opAssign/CC completely,
opting for a bit copy, which is illegal.
September 10, 2012
On Monday, September 10, 2012 11:49:48 monarch_dodra wrote:
> It appears that when writting:
> tests[4] = Test("Foobar");
> It *looks* like compiler is eliding the opAssign/CC completely,
> opting for a bit copy, which is illegal.

As I believe was mentioned elsewhere in this thread, that's due to

http://d.puremagic.com/issues/show_bug.cgi?id=6906

AA's work fine for the most part, but they're really quite buggy when it comes to corner cases. A new implementation is being worked on, but it's slow in coming.

- Jonathan M Davis
September 10, 2012
On Monday, 10 September 2012 at 09:54:46 UTC, Jonathan M Davis wrote:
> On Monday, September 10, 2012 11:49:48 monarch_dodra wrote:
>> It appears that when writting:
>> tests[4] = Test("Foobar");
>> It *looks* like compiler is eliding the opAssign/CC completely,
>> opting for a bit copy, which is illegal.
>
> As I believe was mentioned elsewhere in this thread, that's due to
>
> http://d.puremagic.com/issues/show_bug.cgi?id=6906
>
> AA's work fine for the most part, but they're really quite buggy when it comes
> to corner cases. A new implementation is being worked on, but it's slow in
> coming.
>
> - Jonathan M Davis

Oops, sorry. TY.
September 11, 2012
On 09/10/2012 02:49 AM, monarch_dodra wrote:
> On Sunday, 9 September 2012 at 23:54:45 UTC, Jonathan M Davis
> wrote:
>>
>> [SNIP]
>>
>> the default assignment operator illegal. You could overload it, and as
>> long as
>> it doesn't touch any of the const member variables, it would work, but
>> the
>> const member variable is stuck as it is, and anything trying to mutate is
>> illegal.
>>
>> [SNIP]
>>
>> - Jonathan M Davis
>
> Not to that it is my goal to be a pain, but the example I
> provided *does* overload opAssign (and the CC), but it *doesn't*
> work.
>
> Notice the error message is:
> "Error: tests[4] isn't mutable"
> Which is simply not true.
>
> The default assignment operator, when trying to do an assignment creates:
> "Error: variable XXX cannot modify struct with immutable members."
> But that is not what we are seeing.
>
> It appears that when writting:
> tests[4] = Test("Foobar");
> It *looks* like compiler is eliding the opAssign/CC completely,
> opting for a bit copy, which is illegal.

I don't see how opAssign is involved here. The problem is with the eager element insertion of the following expression alone:

    tests[4]

That expression does add an element having the default value to the container. Try this program:

import std.stdio;

struct Test
{
    string name;
}

Test alsoPrintLength(Test[uint] aa)
{
    writefln("Adding to this AA: %s", aa);
    return Test();
}

void main()
{
    Test[uint] tests;
    tests[4] = alsoPrintLength(tests);
}

The output:

  Adding to this AA: [4:Test("")]

As it demonstrates, the AA already has an element when alsoPrintLength() is called. The assignment in the last line of the program is assigning to that element which happens to have a const member in your example:

	struct Test {
		const string Name;

		this(string name) {
			this.Name = name;
		}
	}

'this.Name = name' fails to compile for that reason.

Ali

September 11, 2012
On Tuesday, 11 September 2012 at 09:00:15 UTC, Ali Çehreli wrote:
> On 09/10/2012 02:49 AM, monarch_dodra wrote:
> > On Sunday, 9 September 2012 at 23:54:45 UTC, Jonathan M Davis
> > wrote:
> >>
> >> [SNIP]
> >>
> >> the default assignment operator illegal. You could overload
> it, and as
> >> long as
> >> it doesn't touch any of the const member variables, it would
> work, but
> >> the
> >> const member variable is stuck as it is, and anything trying
> to mutate is
> >> illegal.
> >>
> >> [SNIP]
> >>
> >> - Jonathan M Davis
> >
> > Not to that it is my goal to be a pain, but the example I
> > provided *does* overload opAssign (and the CC), but it
> *doesn't*
> > work.
> >
> > Notice the error message is:
> > "Error: tests[4] isn't mutable"
> > Which is simply not true.
> >
> > The default assignment operator, when trying to do an
> assignment creates:
> > "Error: variable XXX cannot modify struct with immutable
> members."
> > But that is not what we are seeing.
> >
> > It appears that when writting:
> > tests[4] = Test("Foobar");
> > It *looks* like compiler is eliding the opAssign/CC
> completely,
> > opting for a bit copy, which is illegal.
>
> I don't see how opAssign is involved here. The problem is with the eager element insertion of the following expression alone:
>
>     tests[4]
>
> That expression does add an element having the default value to the container.

No arguments there. tests[4] first creates an element initialized to the value of Test.init.

> [SNIP]
>
> 'this.Name = name' fails to compile for that reason.
>
> Ali

The difference is that the opAssign operator I defined specifically does not attempt to modify the const member, so assigning to an already existing object is legal.

Even with that though, I have:

void main()
{
    Test t1;
    Test[4] testsArray;
    Test[int] tests;

    t1 = Test("hello");            // (1)
    testsArray[3] = Test("hello"); // (2)
    tests[4] = Test("hello");      // (3)
}

In this program:
(1) compiles and is perfectly legal.
(2) ditto.
(3) This fails to compile, but it has no reason not to.


1 2
Next ›   Last »