Re: Frustrations with const
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 hst...@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.
Re: Frustrations with const
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.
Re: Frustrations with const
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.
[OT] mutt settings (Was: Re: Frustrations with const)
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
Frustrations with const
I'm writing an AA implementation, and ran into this problem with the way const behaves in D. Basically, I have an auxiliary function that searches the internal hash table for a given key, and returns the slot containing the matching entry, if found. 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). Is there any way to work around this? Or more importantly, why does the compiler force all internal members of this to be const inside a const method, when what it really should be enforcing is that nothing is being *modified*? What's wrong with extracting non-const members from the object in a const method, if you never actually do anything to it? T -- Never wrestle a pig. You both get covered in mud, and the pig likes it.
Re: Frustrations with const
On 03/08/2012 08:09 PM, H. S. Teoh wrote: I'm writing an AA implementation, and ran into this problem with the way const behaves in D. Basically, I have an auxiliary function that searches the internal hash table for a given key, and returns the slot containing the matching entry, if found. 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). Is there any way to work around this? Or more importantly, why does the compiler force all internal members of this to be const inside a const method, when what it really should be enforcing is that nothing is being *modified*? What's wrong with extracting non-const members from the object in a const method, if you never actually do anything to it? T inout(Slot)* findSlot(Key key) inout { ... }
Re: Frustrations with const
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.
Re: Frustrations with const
On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh hst...@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
Re: Frustrations with const
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 hst...@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
Re: Frustrations with const
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
Re: Frustrations with const
On Thu, 08 Mar 2012 15:06:19 -0500, H. S. Teoh hst...@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 hst...@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