March 08, 2012
On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
> On 03/08/2012 08:09 PM, H. S. Teoh wrote:
[...]
> >The problem is, how to write this function so that it can be called from *both* a const public method and a non-const public method? Since the method itself doesn't actually modify anything, it *should* in theory be possible to mark it as const:
> >
> >	const Slot *findSlot(Key key) { ... }
> >
> >However, because the const applies to 'this', the compiler insists that referencing anything via 'this', including reading a pointer to a slot, must also be const, so it refuses to let the return type be Slot*; it has to be const(Slot)*.
> >
> >But this is silly, because now the caller isn't allowed to modify the Slot either, so now I need to bloat the code with two identical copies of findSlot, one with const, and one without (since if it wasn't marked const, then a const method couldn't call it).
[...]
> inout(Slot)* findSlot(Key key) inout { ... }

Ahhh. Thanks!

But that still doesn't solve the problem:

	inout(Slot)* findSlot(Key key) inout {
		auto slot = slots[hash(key)];
		while (slot) {
			if (slot.hash == hash(key) && slot.key == key)
				return slot;

			// Error: cannot modify inout(Slot)*
--->			slot = slot.next;
		}
		return null;
	}



T

-- 
Help a man when he is in trouble and he will remember you when he is in trouble again.
March 08, 2012
On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:

> On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
>> On 03/08/2012 08:09 PM, H. S. Teoh wrote:
> [...]
>> >The problem is, how to write this function so that it can be called  
>> from
>> >*both* a const public method and a non-const public method? Since the
>> >method itself doesn't actually modify anything, it *should* in theory  
>> be
>> >possible to mark it as const:
>> >
>> >	const Slot *findSlot(Key key) { ... }
>> >
>> >However, because the const applies to 'this', the compiler insists that
>> >referencing anything via 'this', including reading a pointer to a slot,
>> >must also be const, so it refuses to let the return type be Slot*; it
>> >has to be const(Slot)*.
>> >
>> >But this is silly, because now the caller isn't allowed to modify the
>> >Slot either, so now I need to bloat the code with two identical copies
>> >of findSlot, one with const, and one without (since if it wasn't marked
>> >const, then a const method couldn't call it).
> [...]
>> inout(Slot)* findSlot(Key key) inout { ... }
>
> Ahhh. Thanks!
>
> But that still doesn't solve the problem:
>
> 	inout(Slot)* findSlot(Key key) inout {
> 		auto slot = slots[hash(key)];

What is type slot, and how is it constructed?  This snippit isn't enough to provide help.

> 		while (slot) {
> 			if (slot.hash == hash(key) && slot.key == key)
> 				return slot;
>
> 			// Error: cannot modify inout(Slot)*

An exact message is preferrable.

> --->			slot = slot.next;
> 		}
> 		return null;
> 	}

-Steve
March 08, 2012
On 03/08/2012 08:49 PM, H. S. Teoh wrote:
> On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
>> On 03/08/2012 08:09 PM, H. S. Teoh wrote:
> [...]
>>> The problem is, how to write this function so that it can be called from
>>> *both* a const public method and a non-const public method? Since the
>>> method itself doesn't actually modify anything, it *should* in theory be
>>> possible to mark it as const:
>>>
>>> 	const Slot *findSlot(Key key) { ... }
>>>
>>> However, because the const applies to 'this', the compiler insists that
>>> referencing anything via 'this', including reading a pointer to a slot,
>>> must also be const, so it refuses to let the return type be Slot*; it
>>> has to be const(Slot)*.
>>>
>>> But this is silly, because now the caller isn't allowed to modify the
>>> Slot either, so now I need to bloat the code with two identical copies
>>> of findSlot, one with const, and one without (since if it wasn't marked
>>> const, then a const method couldn't call it).
> [...]
>> inout(Slot)* findSlot(Key key) inout { ... }
>
> Ahhh. Thanks!
>
> But that still doesn't solve the problem:
>
> 	inout(Slot)* findSlot(Key key) inout {
> 		auto slot = slots[hash(key)];

inout(Slot)* slot = slots[hash(key)];

> 		while (slot) {
> 			if (slot.hash == hash(key)&&  slot.key == key)
> 				return slot;
>
> 			// Error: cannot modify inout(Slot)*
> --->			slot = slot.next;
> 		}
> 		return null;
> 	}
>
>
>
> T
>
March 08, 2012
On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:
> On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> 
> >On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
[...]
> >>inout(Slot)* findSlot(Key key) inout { ... }
> >
> >Ahhh. Thanks!
> >
> >But that still doesn't solve the problem:
> >
> >	inout(Slot)* findSlot(Key key) inout {
> >		auto slot = slots[hash(key)];
> 
> What is type slot, and how is it constructed?  This snippit isn't enough to provide help.
[...]

Slot is a struct, and slots is Slots*[].  But anyway, I found the problem.  I needed to explicitly declare slot as:

	inout(Slot)* slot = ...

because for whatever reason, auto turns it into inout(Slot*) which
cannot be modified.

I think inout is one of those things that really needs more thorough treatment for newbies, because coming from a C/C++ background I had no idea what was wrong. Now that I get it, it makes so much more sense.


T

-- 
Life would be easier if I had the source code. -- YHL
March 08, 2012
On Thu, 08 Mar 2012 15:06:19 -0500, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:

> On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:
>> On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh
>> <hsteoh@quickfur.ath.cx> wrote:
>>
>> >On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
> [...]
>> >>inout(Slot)* findSlot(Key key) inout { ... }
>> >
>> >Ahhh. Thanks!
>> >
>> >But that still doesn't solve the problem:
>> >
>> >	inout(Slot)* findSlot(Key key) inout {
>> >		auto slot = slots[hash(key)];
>>
>> What is type slot, and how is it constructed?  This snippit isn't
>> enough to provide help.
> [...]
>
> Slot is a struct, and slots is Slots*[].  But anyway, I found the
> problem.  I needed to explicitly declare slot as:
>
> 	inout(Slot)* slot = ...
>
> because for whatever reason, auto turns it into inout(Slot*) which
> cannot be modified.

I was wondering, because your error message identified it as inout(Slot)*, which should be modifiable...

> I think inout is one of those things that really needs more thorough
> treatment for newbies, because coming from a C/C++ background I had no
> idea what was wrong. Now that I get it, it makes so much more sense.

It's kind of a new concept to D even (since 2.056).  It's not completely fleshed out yet, Timon, Kenji, and Stuart have some great ideas on making it better.

This article might help: http://drdobbs.com/blogs/cpp/231902461

I plan to write a const/inout article at some point.

-Steve
March 09, 2012
On 03/08/2012 09:06 PM, H. S. Teoh wrote:
> On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:
>> On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh
>> <hsteoh@quickfur.ath.cx>  wrote:
>>
>>> On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
> [...]
>>>> inout(Slot)* findSlot(Key key) inout { ... }
>>>
>>> Ahhh. Thanks!
>>>
>>> But that still doesn't solve the problem:
>>>
>>> 	inout(Slot)* findSlot(Key key) inout {
>>> 		auto slot = slots[hash(key)];
>>
>> What is type slot, and how is it constructed?  This snippit isn't
>> enough to provide help.
> [...]
>
> Slot is a struct, and slots is Slots*[].  But anyway, I found the
> problem.  I needed to explicitly declare slot as:
>
> 	inout(Slot)* slot = ...
>
> because for whatever reason, auto turns it into inout(Slot*) which
> cannot be modified.

Probably it does not. What is the type of the "slots" hashtable?


>
> I think inout is one of those things that really needs more thorough
> treatment for newbies, because coming from a C/C++ background I had no
> idea what was wrong. Now that I get it, it makes so much more sense.
>
>
> T
>

This is a general issue with how auto infers types. It would often be useful to get the head-mutable type out of the type deduction instead of the actual type.
March 09, 2012
On Fri, Mar 09, 2012 at 11:24:46AM +0100, Timon Gehr wrote:
> On 03/08/2012 09:06 PM, H. S. Teoh wrote:
> >On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:
[...]
> >>What is type slot, and how is it constructed?  This snippit isn't enough to provide help.
> >[...]
> >
> >Slot is a struct, and slots is Slots*[].  But anyway, I found the problem.  I needed to explicitly declare slot as:
> >
> >	inout(Slot)* slot = ...
> >
> >because for whatever reason, auto turns it into inout(Slot*) which
> >cannot be modified.
> 
> Probably it does not. What is the type of the "slots" hashtable?

Here are the relevant declarations:

    struct Slot
    {
        Slot   *next;
        hash_t  hash;
        Key     key;
        Value   value;

        this(hash_t h, Key k, Value v)
        {
            hash = h;
            key = k;
            value = v;
        }
    }

    struct Impl
    {
        Slot*[]  slots;
        size_t   nodes;

        // Prevent extra allocations for very small AA's.
        Slot*[4] binit;
    }


[...]
> >I think inout is one of those things that really needs more thorough treatment for newbies, because coming from a C/C++ background I had no idea what was wrong. Now that I get it, it makes so much more sense.
[...]
> This is a general issue with how auto infers types. It would often be useful to get the head-mutable type out of the type deduction instead of the actual type.

Yeah, that would be very useful.


T

-- 
Tech-savvy: euphemism for nerdy.
March 09, 2012
On Friday, 9 March 2012 at 15:30:50 UTC, H. S. Teoh wrote:
> Yeah, that would be very useful.

I think it was actually decided to do that... they
made the change for templates already.


PS: you might want to take a look at your mutt settings.
Your replies seem to have a truncated References header
which messes up threading in many clients.
March 09, 2012
On Fri, Mar 09, 2012 at 04:39:13PM +0100, Adam D. Ruppe wrote: [...]
> PS: you might want to take a look at your mutt settings.  Your replies seem to have a truncated References header which messes up threading in many clients.

Oh really? I don't think I changed any settings related to that. AFAICT it does generate the right references header. How do I fix it?

P.S. I do have mutt set on mailing list mode when replying to this list, though, and I usually reply using 'L'. Does that make a difference?


T

-- 
Computerese Irregular Verb Conjugation: I have preferences.  You have biases.  He/She has prejudices. -- Gene Wirchenko
Top | Discussion index | About this forum | D home