Best practices for logical const

Steven Schveighoffer schveiguy at yahoo.com
Sat Feb 15 18:39:58 PST 2014


On Fri, 14 Feb 2014 23:03:50 -0500, Adam D. Ruppe  
<destructionator at gmail.com> wrote:

> D doesn't have logical const, but sometimes it is useful, especially  
> with lazy initialization of a field, and we can kinda fake it with casts  
> or with global variables. Modifying an immutable object is undefined  
> behavior, so how can we avoid that, and if not, try to minimize the  
> problems in practice?
>
> Using global variables to store local state is kinda silly, it seems to  
> me that doing a AA lookup kinda defeats the point of caching in the  
> first place, so I want to focus on the cast method.
>
> So:
>
> * should we always wrap the write in a synchronized block to minimize  
> the chances that we'll have thread problems with implicitly shared  
> immutable things passed as const? What's the best way to do this btw?

As a start, I would take a look at the code that generates the mutex when  
you synchronize an object. It is the only case where logical const is  
allowed in D.

> * should objects with logical const methods deliberately not provide  
> immutable constructors to prevent them from being immutable? Would this  
> actually work?

This is a good idea. Can you @disable the immutable constructor?

> * Anything else that is likely to come up?

Where you must be very very cautious is immutable pure functions. The  
compiler may make assumptions that are not correct in terms of shortcuts.

My advice is to never change "logical const" data inside a const pure  
function.

Other than that, depending on the use case, use C threading rules when  
making changes. Basically, if you know the object will never be referenced  
in multiple threads (very application specific), then you are OK to just  
change it. Otherwise, I'd put a mutex on it, or (ironically) use the  
object's monitor to protect it.

-Steve


More information about the Digitalmars-d mailing list