Const Variables

Ali Çehreli acehreli at yahoo.com
Sun Apr 3 22:42:15 UTC 2022


On 4/3/22 11:24, Salih Dincer wrote:
 > On Sunday, 3 April 2022 at 14:29:22 UTC, Paul Backus wrote:
 >> On Sunday, 3 April 2022 at 13:50:28 UTC, Salih Dincer wrote:
 >>> Hi all,
 >>>
 >>> Do you have a good example of how const variables actually work?

You are right that const is not absolutely necessary. However, it is 
such a useful concept that some programming languages don't allow 
mutation at all.

Immutability is seen to be so valuable that some people argue that the 
default in D should be immutable. (Rust is just one example where the 
default is const. In that language, you have to use 'mut' (presumably 
short for "mutable") for variables that can be mutated.)

 >> This is covered in the const FAQ:
 >>
 >> https://dlang.org/articles/const-faq.html
 >
 > The programs I write are not multithreaded. Also, I don't work as a
 > team.

So you agree with that article. :) The rest of us who work with 
multi-threaded programs or with other developers agree with it as well. ;)

 > Thanks for the link but there is only the following example:
 >
 > ```d
 > struct Foo
 > {
 >      mutable int len;

Wow! That article must be from the early days of D. There is no 
'mutable' in D (any more?).

 >      mutable bool len_done;
 >      const char* str;
 >      int length()
 >      {
 >          if (!len_done)
 >          {
 >              len = strlen(str);
 >              len_done = true;

That example is the concept of logical constness, where the object 
computes some value as neeeded and caches the result for later use. The 
member 'len' (and len_done) is modified even if the 'f' object below is 
const. However, the example doesn't fit today's D because the function 
should have been marked as 'const' as well:

int length() const {
   // ...
}

In any case, there is no logical constness in D. (However, one can play 
tricks like using casts. (Which may be undefined behavior, etc. etc.))

 >          }
 >          return len;
 >      }
 >      this(char* str) { this.str = str; }
 > }
 > const Foo f = Foo("hello");
 > bar(f.length);

So, there is the 'const' object f and calling its length() member 
function, which mutates two members of the object. As those mutations do 
not change the value of the object, the object is considered still the 
same. In other words, caching something about the object is considered 
to not change that object. That's what is meant with logical const: 
There has been changes but they did not change the state of the object.

Ali



More information about the Digitalmars-d-learn mailing list